Commit feae79dd authored by xinzhedeai's avatar xinzhedeai

add:同步 from liqilin 1219

parent 47dfce11
......@@ -68,5 +68,7 @@ VITE_SERVICE_URL=http://192.168.2.53:9995
# 模型地址环境
VITE_MODEL_URL=http://192.168.2.53:9995/model
# 开发环境 - WebSocket 全局地址
# VITE_WEBSOCKET_URL=ws://192.168.3.248:9996
\ No newline at end of file
......@@ -6,17 +6,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<!-- 外部 - 依赖库 -->
<!-- <script src="./public/js/proj4.js"></script>
<script src="./public/js/turf.min.js"></script>
<script src="./public/js/echarts.min.js"></script> -->
<!-- 外部 - 依赖库 -->
<script src="./public/js/proj4.js"></script>
<script src="./public/js/turf.min.js"></script>
<link rel="stylesheet" type="text/css" href="./Cesium/Widgets/widgets.css" />
<script type="text/javascript" src="/public/webrtcstreamer.js"></script>
<script type="text/javascript" src="./Cesium/Cesium.js"></script>
<script src="./public/codebase/webVideoCtrl.js"></script>
<script src="./public/jquery-1.7.1.min.js"></script>
<script src="/public/jquery-1.7.1.min.js"></script>
<title>%VITE_APP_TITLE%</title>
</head>
......
......@@ -29,9 +29,15 @@ importers:
'@sa/utils':
specifier: workspace:*
version: link:packages/utils
'@vicons/fa':
specifier: ^0.13.0
version: 0.13.0
'@vicons/fluent':
specifier: ^0.13.0
version: 0.13.0
'@vicons/ionicons4':
specifier: ^0.13.0
version: 0.13.0
'@vueuse/core':
specifier: 14.0.0
version: 14.0.0(vue@3.5.22(typescript@5.9.3))
......@@ -1455,9 +1461,15 @@ packages:
cpu: [x64]
os: [win32]
'@vicons/fa@0.13.0':
resolution: {integrity: sha512-BFcDewcT78fSn4Y/fOgqlswbLUEW3+qJK2iJiNtgmkMzadBVpDXhNyVKsYM3V2uKPvDUrZT0JCWDWVRCiBXJZA==}
'@vicons/fluent@0.13.0':
resolution: {integrity: sha512-bYGZsOE3qzvm3Cm43e7tybgGlr5ZUpYqtRZq0g0Tfupe8jIzLolpvQLNUt1zS8Mgt6goTbUk5YH7Fkv16jkykg==}
'@vicons/ionicons4@0.13.0':
resolution: {integrity: sha512-5WHIl/4R5a4i9GONa+hIQWxg/WczrbsCdqxawHZvdd3drsEr+Q3yzlfS+NNRO4WS3uDW2uWLCwoW+yp5TgcKeQ==}
'@vicons/ionicons5@0.13.0':
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
......@@ -5441,8 +5453,12 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
optional: true
'@vicons/fa@0.13.0': {}
'@vicons/fluent@0.13.0': {}
'@vicons/ionicons4@0.13.0': {}
'@vicons/ionicons5@0.13.0': {}
'@vitejs/plugin-vue-jsx@5.1.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(sass@1.93.3)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3))':
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
define(function(require, exports, module) {
var _oCommon, _oUtils, _oBase64;
require("websdk");
_oCommon = require("common");
_oUtils = require("utils");
_oBase64 = require("base64");
function EncryptionFac () {}
EncryptionFac.prototype.encrypt = function (oStr, iRSABits, bBase64Encrypted, cbFun) {
//var that = this;
var iBits = 1024;
if (iRSABits) {
iBits = iRSABits;
}
var szPassPhrase = new Date() + "",
szMattsRSAkey = cryptico.generateRSAKey(szPassPhrase, iBits),
szPublicKeyString = cryptico.publicKeyString(szMattsRSAkey),
szXml = "<?xml version='1.0' encoding='UTF-8'?><PublicKey><key>" + _oBase64.encode(szPublicKeyString) + "</key></PublicKey>",
oXmlDoc = _oUtils.parseXmlFromStr(szXml);
WebSDK.WSDK_Request(_oCommon.m_szHostName, _oCommon.m_iHttpProtocal, _oCommon.m_iHttpPort, {
cmd: "challenge",
type: "POST",
data: oXmlDoc,
success: function (status, xmlDoc) {
var szDecryptionResult = cryptico.decrypt(_oBase64.decode(_oUtils.nodeValue(xmlDoc, "key")), szMattsRSAkey);
if(szDecryptionResult.plaintext != null) {
var szKey,szEncryptPassword;
var aResult = [];
if (iBits === 256) {
szKey = _oUtils.toHex(szDecryptionResult.plaintext);
} else {
szKey = szDecryptionResult.plaintext;
}
szEncryptPassword = aes_encrypt(szDecryptionResult.plaintext.substring(0, 16), szKey, true);
if("function" === typeof cbFun) {
if("string" === typeof oStr) {
bBase64Encrypted && ( oStr = _oBase64.encode(oStr) );
cbFun( _oBase64.encode( szEncryptPassword + _oUtils.encodeAES(oStr, szKey, "", "ecb") ) );
} else if("[object Array]" === Object.prototype.toString.call(oStr)) {
for(var i = 0, iArrayLen = oStr.length; i < iArrayLen; i++) {
bBase64Encrypted && ( oStr[i] = _oBase64.encode(oStr[i]) );
var szTemp = szEncryptPassword + _oUtils.encodeAES(oStr[i], szKey, "", "ecb");
aResult.push( _oBase64.encode(szTemp) );
}
cbFun(aResult);
}
}
}
}
});
};
EncryptionFac.prototype.encryptSync = function (oStr, iRSABits, bBase64Encrypted) {
//var that = this;
var iBits = 1024;
var aResult = [];
if (iRSABits) {
iBits = iRSABits;
}
var szPassPhrase = new Date() + "",
szMattsRSAkey = cryptico.generateRSAKey(szPassPhrase, iBits),
szPublicKeyString = cryptico.publicKeyString(szMattsRSAkey),
szXml = "<?xml version='1.0' encoding='UTF-8'?><PublicKey><key>" + _oBase64.encode(szPublicKeyString) + "</key></PublicKey>",
oXmlDoc = _oUtils.parseXmlFromStr(szXml);
WebSDK.WSDK_Request(_oCommon.m_szHostName, _oCommon.m_iHttpProtocal, _oCommon.m_iHttpPort, {
cmd: "challenge",
type: "POST",
async: false,
data: oXmlDoc,
success: function (status, xmlDoc) {
var szDecryptionResult = cryptico.decrypt(_oBase64.decode(_oUtils.nodeValue(xmlDoc, "key")), szMattsRSAkey);
if(szDecryptionResult.plaintext != null) {
var szKey, szEncryptPassword;
if (iBits === 256) {
szKey = _oUtils.toHex(szDecryptionResult.plaintext);
} else {
szKey = szDecryptionResult.plaintext;
}
szEncryptPassword = aes_encrypt(szDecryptionResult.plaintext.substring(0, 16), szKey, true);
if("string" === typeof oStr) {
bBase64Encrypted && ( oStr = _oBase64.encode(oStr) );
aResult.push( _oBase64.encode( szEncryptPassword + _oUtils.encodeAES(oStr, szKey, "", "ecb") ) );
} else {
for(var i = 0, iArrayLen = oStr.length; i < iArrayLen; i++) {
bBase64Encrypted && ( oStr[i] = _oBase64.encode(oStr[i]) );
var szTemp = szEncryptPassword + _oUtils.encodeAES(oStr[i], szKey, "", "ecb");
aResult.push( _oBase64.encode(szTemp) );
}
}
}
}
});
if("string" === typeof oStr) {
return aResult[0];
} else {
return aResult;
}
};
module.exports = new EncryptionFac();
});
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
This source diff could not be displayed because it is too large. You can view the blob instead.
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
importScripts('libSystemTransform.js');
const RECORDRTP = 0; //录制一份未经过转封装的码流原始数据,用于定位问题
let dataType = 1;
// 字母字符串转byte数组
function stringToBytes (str) {
var ch;
var st;
var re = [];
for (var i = 0; i < str.length; i++) {
ch = str.charCodeAt(i); // get char
st = []; // set up "stack"
do {
st.push(ch & 0xFF); // push byte to stack
ch = ch >> 8; // shift value down by 1 byte
}
while (ch);
// add stack contents to result
// done because chars have "wrong" endianness
re = re.concat(st.reverse());
}
// return an array of bytes
return re;
}
// 转封装库回调函数
self.STCallBack = function (fileIndex, indexLen, data, dataLen) {
//stFrameInfo的类型见DETAIL_FRAME_INFO
let stFrameInfo = Module._GetDetialFrameInfo();
let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " , stFrameInfo);
//console.log("nIsMp4Index is " + nIsMp4Index);
//debugger
var pData = null;
pData = new Uint8Array(dataLen);
pData.set(Module.HEAPU8.subarray(data, data + dataLen));
if (dataType === 1) {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 1,
frameInfo: stFrameInfo }, [pData.buffer]);
dataType = 2;
} else {
if (nIsMp4Index) {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 6,
frameInfo: stFrameInfo }, [pData.buffer]); //6:索引类型
} else {
postMessage({ type: "outputData",
buf: pData.buffer,
dType: 2,
frameInfo: stFrameInfo }, [pData.buffer]); //2:码流
}
}
//stFrameInfo的类型见DETAIL_FRAME_INFO
//let stFrameInfo = Module._GetDetialFrameInfo();
//let stFrameType = stFrameInfo.nFrameType;
//let nFrameNum = stFrameInfo.nFrameNum;
//let nTimeStamp = stFrameInfo.nTimeStamp;
//let nIsMp4Index = stFrameInfo.nIsMp4Index;
//console.log("FrameType is " + stFrameType);
//console.log("nIsMp4Index is " + nIsMp4Index);
};
// self.Module = { memoryInitializerRequest: loadMemInitFile(), TOTAL_MEMORY: 128*1024*1024 };
// importScripts('SystemTransform.js');
self.Module['onRuntimeInitialized'] = function () {
postMessage({type: "loaded"});
};
onmessage = function (e) {
var data = e.data;
if ("create" === data.type) {
if (RECORDRTP) {
postMessage({ type: "created" });
postMessage({ type: "outputData",
buf: data.buf,
dType: 1 }, [data.buf]);
} else {
var iHeadLen = data.len;
var pHead = Module._malloc(iHeadLen);
if (pHead === null) {
console.log("inputdata malloc failed!!!");
return -1;
}
var iTransType = data.packType;//目标格式
var iRet = 0;
var buf = new Uint8Array(data.buf);
//PS流(只有ps支持探测),并且编码格式异常(正常是265和264,11位和10位 不可能全是0,全0 并且是ps就探测策略)的情况下,使用探测策略
if (buf[9] === 0 && buf[8] === 2 && buf[11] === 0 && buf[10] === 0) {
iRet = Module._CreatHandle(0, iTransType, iHeadLen); //用探测的策略
} else {
self.writeArrayToMemory(buf, pHead);
iRet = Module._CreatHandle(pHead, iTransType, iHeadLen);
//-2147483645代表的是参数错误,此种情况,大概率发生在头信息错误,例如大华设备的情况,此时用 无头探测的策略
//其他情况 按海康标准处理流程,不要做任何特殊处理
if (iRet == -2147483645) {
iRet = Module._CreatHandle(0, iTransType, iHeadLen); //失败了,用探测的策略再试一次
}
}
if (iRet != 0) {
if (iRet == -2147483647) {
postMessage({ type: "outputData",
dType: 1501 }); //标记为格式不支持
} else {
postMessage({ type: "outputData",
dType: 1501 }); //转封装创建失败,也同样提示码流格式不支持,如果后续要细化再区分
}
console.log("_CreatHandle failed!" + iRet);
} else {
if (data.options && typeof data.options.pKeyData !== "undefined" && data.options.pKeyData !== null) {
if ((2 === iTransType && "" === data.options.pKeyData)) {
//转ps的时候,如果密码是空是允许的,即使码流加密了,导出加密后的码流就行
//此时不要设置密码否则反而会提示密码错误
} else {
var secretInfo = data.options;
var keyLen = secretInfo.nKeyLen;
var pKeyData = Module._malloc(keyLen);
if (pKeyData === null) {
console.log("setEncryptKey malloc failed!!!");
return -1;
}
var nKeySize = secretInfo.pKeyData.length;
var bufData = stringToBytes(secretInfo.pKeyData);
let inputData = new Uint8Array(bufData);
Module.writeArrayToMemory(inputData, pKeyData);
inputData = null;
iRet = Module._SysTransSetEncryptKey(secretInfo.nKeyType, pKeyData, keyLen, nKeySize);
if (iRet != 0) {
console.log("_SysTransSetEncryptKey failed!");
}
if (pKeyData != null) {
Module._free(pKeyData);
pKeyData = null;
}
}
}
//带samplingParam参数,代表需要 用到 音频替换功能
if (data.options && typeof data.options.samplingParam !== "undefined") {
var oParam = data.options.samplingParam;
var nCapacityType = 1; //写死1 代表 剔除音频
var nType = 3; //写死3 代表 修改输出目标的海康头配置,内部包含视频参数、音频参数
var nAudioEnable = 1; //音频参数修改使能开关,0=不启用,1=启用
var nAudioFormat = oParam.iAudioType; //音频编码类型 对应关系参考海康媒体头规范,PCM 0x7001 G711_U 0x7110 G711_A 0x7111 AAC 0x2001
var nAudioChannels = oParam.iChannel; //音频通道数直接设置为
var nAudioBitsPerSample = oParam.iAudioBitWidth; //音频位样率
var nAudioSamplesrate = oParam.iAudioSamplingRate; //音频采样率
var nAudioBitrate = oParam.iAudioBitRate; //音频比特率
iRet = Module._SysTransConfig(nCapacityType, nType, nAudioEnable, nAudioFormat,
nAudioChannels, nAudioBitsPerSample, nAudioSamplesrate, nAudioBitrate);
if (iRet != 0) {
console.log("_SysTransConfig Failed:" + iRet);
}
} else {
iRet = Module._SysTransConfig(128, 0, 0, 0, 0, 0, 0, 0); //nCapacityType = 0x00000080 代表开启私有信息回调 解决转mp4后,私有信息丢失问题
if (iRet != 0) {
console.log("_SysTransConfig Failed:" + iRet);
}
}
iRet = Module._SysTransRegisterDataCallBack();
if (iRet != 0) {
console.log("_SysTransRegisterDataCallBack Failed:" + iRet);
}
iRet = Module._SysTransStart(null, null);
if (iRet != 0) {
console.log("_SysTransStart Failed:" + iRet);
}
postMessage({type: "created"});
}
if (pHead != null) {
Module._free(pHead);
pHead = null;
}
}
} else if ("inputData" === data.type) {
if (RECORDRTP) {
var aFileData = new Uint8Array(data.buf); // 拷贝一份
var iBufferLen = aFileData.length;
var szBufferLen = iBufferLen.toString(16);
if (szBufferLen.length === 1) {
szBufferLen = "000" + szBufferLen;
} else if (szBufferLen.length === 2) {
szBufferLen = "00" + szBufferLen;
} else if (szBufferLen.length === 3) {
szBufferLen = "0" + szBufferLen;
}
var aData = [0, 0, parseInt(szBufferLen.substring(0, 2), 16), parseInt(szBufferLen.substring(2, 4), 16)];
for (var iIndex = 0, iDataLength = aFileData.length; iIndex < iDataLength; iIndex++) {
aData[iIndex + 4] = aFileData[iIndex];
}
var dataUint8 = new Uint8Array(aData);
postMessage({type: "outputData",
buf: dataUint8.buffer,
dType: 2});
} else {
let inputMode = 0; //代表输入原始数据
if (data.samplingParam) {
iRet = Module._SysTransInputAudioPara(5, data.samplingParam.iChannel, data.samplingParam.iAudioBitWidth,
data.samplingParam.iAudioSamplingRate, data.samplingParam.iTimeStamp, data.samplingParam.iAudioBitRate); //参数含义和_SysTransConfig类似
if (iRet != 0) {
console.log("_SysTransInputAudioPara Failed:" + iRet);
}
inputMode = 2; //输入替换的音频
}
var pInputDataBuf = Module._malloc(data.len);
var idataLen = data.len;
self.writeArrayToMemory(new Uint8Array(data.buf), pInputDataBuf);
// 输入数据,每次最多2m
let pp = Module._SysTransInputData(inputMode, pInputDataBuf, idataLen);
if (pp == -2147483627) {
//-2147483627 对应十六进制的80000015
postMessage({ type: "outputData",
dType: 1500 }); //标记为密码错误
} else if (pp == -2147483647) {
postMessage({ type: "outputData",
dType: 1501 }); //标记为格式不支持
} else if (pp != 0) {
console.log("InputData Failed:" + pp);
}
Module._free(pInputDataBuf);
}
} else if ("release" === data.type) {
var iRet = Module._SysTransStop();
if (iRet != 0) {
console.log("_SysTransStop failed!");
}
Module._SysTransRelease();
if (iRet != 0) {
console.log("_SysTransRelease failed!");
}
close();
}
};
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/*! Sea.js 3.0.1 | seajs.org/LICENSE.md */
!function(a,b){function c(a){return function(b){return{}.toString.call(b)=="[object "+a+"]"}}function d(){return B++}function e(a){return a.match(E)[0]}function f(a){for(a=a.replace(F,"/"),a=a.replace(H,"$1/");a.match(G);)a=a.replace(G,"/");return a}function g(a){var b=a.length-1,c=a.charCodeAt(b);return 35===c?a.substring(0,b):".js"===a.substring(b-2)||a.indexOf("?")>0||47===c?a:a+".js"}function h(a){var b=v.alias;return b&&x(b[a])?b[a]:a}function i(a){var b=v.paths,c;return b&&(c=a.match(I))&&x(b[c[1]])&&(a=b[c[1]]+c[2]),a}function j(a){var b=v.vars;return b&&a.indexOf("{")>-1&&(a=a.replace(J,function(a,c){return x(b[c])?b[c]:a})),a}function k(a){var b=v.map,c=a;if(b)for(var d=0,e=b.length;e>d;d++){var f=b[d];if(c=z(f)?f(a)||a:a.replace(f[0],f[1]),c!==a)break}return c}function l(a,b){var c,d=a.charCodeAt(0);if(K.test(a))c=a;else if(46===d)c=(b?e(b):v.cwd)+a;else if(47===d){var g=v.cwd.match(L);c=g?g[0]+a.substring(1):a}else c=v.base+a;return 0===c.indexOf("//")&&(c=location.protocol+c),f(c)}function m(a,b){if(!a)return"";a=h(a),a=i(a),a=h(a),a=j(a),a=h(a),a=g(a),a=h(a);var c=l(a,b);return c=h(c),c=k(c)}function n(a){return a.hasAttribute?a.src:a.getAttribute("src",4)}function o(a,b,c,d){var e;try{importScripts(a)}catch(f){e=f}b(e)}function p(a,b,c,d){var e=Z.createElement("script");c&&(e.charset=c),A(d)||e.setAttribute("crossorigin",d),q(e,b,a),e.async=!0,e.src=a,ca=e,ba?aa.insertBefore(e,ba):aa.appendChild(e),ca=null}function q(a,b,c){function d(c){a.onload=a.onerror=a.onreadystatechange=null,v.debug||aa.removeChild(a),a=null,b(c)}var e="onload"in a;e?(a.onload=d,a.onerror=function(){D("error",{uri:c,node:a}),d(!0)}):a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&d()}}function r(){if(ca)return ca;if(da&&"interactive"===da.readyState)return da;for(var a=aa.getElementsByTagName("script"),b=a.length-1;b>=0;b--){var c=a[b];if("interactive"===c.readyState)return da=c}}function s(a){function b(){l=a.charAt(k++)}function c(){return/\s/.test(l)}function d(){return'"'==l||"'"==l}function e(){var c=k,d=l,e=a.indexOf(d,c);if(-1==e)k=m;else if("\\"!=a.charAt(e-1))k=e+1;else for(;m>k;)if(b(),"\\"==l)k++;else if(l==d)break;o&&(p.push(a.substring(c,k-1)),o=0)}function f(){for(k--;m>k;)if(b(),"\\"==l)k++;else{if("/"==l)break;if("["==l)for(;m>k;)if(b(),"\\"==l)k++;else if("]"==l)break}}function g(){return/[a-z_$]/i.test(l)}function h(){var b=a.slice(k-1),c=/^[\w$]+/.exec(b)[0];q={"if":1,"for":1,"while":1,"with":1}[c],n={"break":1,"case":1,"continue":1,"debugger":1,"delete":1,"do":1,"else":1,"false":1,"if":1,"in":1,"instanceof":1,"return":1,"typeof":1,"void":1}[c],u="return"==c,s={"instanceof":1,"delete":1,"void":1,"typeof":1,"return":1}.hasOwnProperty(c),o=/^require\s*(?:\/\*[\s\S]*?\*\/\s*)?\(\s*(['"]).+?\1\s*[),]/.test(b),o?(c=/^require\s*(?:\/\*[\s\S]*?\*\/\s*)?\(\s*['"]/.exec(b)[0],k+=c.length-2):k+=/^[\w$]+(?:\s*\.\s*[\w$]+)*/.exec(b)[0].length-1}function i(){return/\d/.test(l)||"."==l&&/\d/.test(a.charAt(k))}function j(){var b=a.slice(k-1),c;c="."==l?/^\.\d+(?:E[+-]?\d*)?\s*/i.exec(b)[0]:/^0x[\da-f]*/i.test(b)?/^0x[\da-f]*\s*/i.exec(b)[0]:/^\d+\.?\d*(?:E[+-]?\d*)?\s*/i.exec(b)[0],k+=c.length-1,n=0}if(-1==a.indexOf("require"))return[];for(var k=0,l,m=a.length,n=1,o=0,p=[],q=0,r=[],s,t=[],u;m>k;)if(b(),c())!u||"\n"!=l&&"\r"!=l||(s=0,u=0);else if(d())e(),n=1,u=0,s=0;else if("/"==l)if(b(),"/"==l)k=a.indexOf("\n",k),-1==k&&(k=a.length);else if("*"==l){var v=a.indexOf("\n",k);k=a.indexOf("*/",k),-1==k?k=m:k+=2,u&&-1!=v&&k>v&&(s=0,u=0)}else n?(f(),n=0,u=0,s=0):(k--,n=1,u=0,s=1);else if(g())h();else if(i())j(),u=0,s=0;else if("("==l)r.push(q),n=1,u=0,s=1;else if(")"==l)n=r.pop(),u=0,s=0;else if("{"==l)u&&(s=1),t.push(s),u=0,n=1;else if("}"==l)s=t.pop(),n=!s,u=0;else{var w=a.charAt(k);";"==l?s=0:"-"==l&&"-"==w||"+"==l&&"+"==w||"="==l&&">"==w?(s=0,k++):s=1,n="]"!=l,u=0}return p}function t(a,b){this.uri=a,this.dependencies=b||[],this.deps={},this.status=0,this._entry=[]}if(!a.seajs){var u=a.seajs={version:"3.0.1"},v=u.data={},w=c("Object"),x=c("String"),y=Array.isArray||c("Array"),z=c("Function"),A=c("Undefined"),B=0,C=v.events={};u.on=function(a,b){var c=C[a]||(C[a]=[]);return c.push(b),u},u.off=function(a,b){if(!a&&!b)return C=v.events={},u;var c=C[a];if(c)if(b)for(var d=c.length-1;d>=0;d--)c[d]===b&&c.splice(d,1);else delete C[a];return u};var D=u.emit=function(a,b){var c=C[a];if(c){c=c.slice();for(var d=0,e=c.length;e>d;d++)c[d](b)}return u},E=/[^?#]*\//,F=/\/\.\//g,G=/\/[^\/]+\/\.\.\//,H=/([^:\/])\/+\//g,I=/^([^\/:]+)(\/.+)$/,J=/{([^{]+)}/g,K=/^\/\/.|:\//,L=/^.*?\/\/.*?\//;u.resolve=m;var M="undefined"==typeof window&&"undefined"!=typeof importScripts&&z(importScripts),N=/^(about|blob):/,O,P,Q=!location.href||N.test(location.href)?"":e(location.href);if(M){var R;try{var S=Error();throw S}catch(T){R=T.stack.split("\n")}R.shift();for(var U,V=/.*?((?:http|https|file)(?::\/{2}[\w]+)(?:[\/|\.]?)(?:[^\s"]*)).*?/i,W=/(.*?):\d+:\d+\)?$/;R.length>0;){var X=R.shift();if(U=V.exec(X),null!=U)break}var Y;if(null!=U)var Y=W.exec(U[1])[1];P=Y,O=e(Y||Q),""===Q&&(Q=O)}else{var Z=document,$=Z.scripts,_=Z.getElementById("seajsnode")||$[$.length-1];P=n(_),O=e(P||Q)}if(M)u.request=o;else{var Z=document,aa=Z.head||Z.getElementsByTagName("head")[0]||Z.documentElement,ba=aa.getElementsByTagName("base")[0],ca;u.request=p}var da,ea=u.cache={},fa,ga={},ha={},ia={},ja=t.STATUS={FETCHING:1,SAVED:2,LOADING:3,LOADED:4,EXECUTING:5,EXECUTED:6,ERROR:7};t.prototype.resolve=function(){for(var a=this,b=a.dependencies,c=[],d=0,e=b.length;e>d;d++)c[d]=t.resolve(b[d],a.uri);return c},t.prototype.pass=function(){for(var a=this,b=a.dependencies.length,c=0;c<a._entry.length;c++){for(var d=a._entry[c],e=0,f=0;b>f;f++){var g=a.deps[a.dependencies[f]];g.status<ja.LOADED&&!d.history.hasOwnProperty(g.uri)&&(d.history[g.uri]=!0,e++,g._entry.push(d),g.status===ja.LOADING&&g.pass())}e>0&&(d.remain+=e-1,a._entry.shift(),c--)}},t.prototype.load=function(){var a=this;if(!(a.status>=ja.LOADING)){a.status=ja.LOADING;var c=a.resolve();D("load",c);for(var d=0,e=c.length;e>d;d++)a.deps[a.dependencies[d]]=t.get(c[d]);if(a.pass(),a._entry.length)return a.onload(),b;var f={},g;for(d=0;e>d;d++)g=ea[c[d]],g.status<ja.FETCHING?g.fetch(f):g.status===ja.SAVED&&g.load();for(var h in f)f.hasOwnProperty(h)&&f[h]()}},t.prototype.onload=function(){var a=this;a.status=ja.LOADED;for(var b=0,c=(a._entry||[]).length;c>b;b++){var d=a._entry[b];0===--d.remain&&d.callback()}delete a._entry},t.prototype.error=function(){var a=this;a.onload(),a.status=ja.ERROR},t.prototype.exec=function(){function a(b){var d=c.deps[b]||t.get(a.resolve(b));if(d.status==ja.ERROR)throw Error("module was broken: "+d.uri);return d.exec()}var c=this;if(c.status>=ja.EXECUTING)return c.exports;if(c.status=ja.EXECUTING,c._entry&&!c._entry.length&&delete c._entry,!c.hasOwnProperty("factory"))return c.non=!0,b;var e=c.uri;a.resolve=function(a){return t.resolve(a,e)},a.async=function(b,c){return t.use(b,c,e+"_async_"+d()),a};var f=c.factory,g=z(f)?f.call(c.exports={},a,c.exports,c):f;return g===b&&(g=c.exports),delete c.factory,c.exports=g,c.status=ja.EXECUTED,D("exec",c),c.exports},t.prototype.fetch=function(a){function c(){u.request(g.requestUri,g.onRequest,g.charset,g.crossorigin)}function d(a){delete ga[h],ha[h]=!0,fa&&(t.save(f,fa),fa=null);var b,c=ia[h];for(delete ia[h];b=c.shift();)a===!0?b.error():b.load()}var e=this,f=e.uri;e.status=ja.FETCHING;var g={uri:f};D("fetch",g);var h=g.requestUri||f;return!h||ha.hasOwnProperty(h)?(e.load(),b):ga.hasOwnProperty(h)?(ia[h].push(e),b):(ga[h]=!0,ia[h]=[e],D("request",g={uri:f,requestUri:h,onRequest:d,charset:z(v.charset)?v.charset(h):v.charset,crossorigin:z(v.crossorigin)?v.crossorigin(h):v.crossorigin}),g.requested||(a?a[g.requestUri]=c:c()),b)},t.resolve=function(a,b){var c={id:a,refUri:b};return D("resolve",c),c.uri||u.resolve(c.id,b)},t.define=function(a,c,d){var e=arguments.length;1===e?(d=a,a=b):2===e&&(d=c,y(a)?(c=a,a=b):c=b),!y(c)&&z(d)&&(c=b===s?[]:s(""+d));var f={id:a,uri:t.resolve(a),deps:c,factory:d};if(!M&&!f.uri&&Z.attachEvent&&b!==r){var g=r();g&&(f.uri=g.src)}D("define",f),f.uri?t.save(f.uri,f):fa=f},t.save=function(a,b){var c=t.get(a);c.status<ja.SAVED&&(c.id=b.id||a,c.dependencies=b.deps||[],c.factory=b.factory,c.status=ja.SAVED,D("save",c))},t.get=function(a,b){return ea[a]||(ea[a]=new t(a,b))},t.use=function(b,c,d){var e=t.get(d,y(b)?b:[b]);e._entry.push(e),e.history={},e.remain=1,e.callback=function(){for(var b=[],d=e.resolve(),f=0,g=d.length;g>f;f++)b[f]=ea[d[f]].exec();c&&c.apply(a,b),delete e.callback,delete e.history,delete e.remain,delete e._entry},e.load()},u.use=function(a,b){return t.use(a,b,v.cwd+"_use_"+d()),u},t.define.cmd={},a.define=t.define,u.Module=t,v.fetchedList=ha,v.cid=d,u.require=function(a){var b=t.get(t.resolve(a));return b.status<ja.EXECUTING&&(b.onload(),b.exec()),b.exports},v.base=O,v.dir=O,v.loader=P,v.cwd=Q,v.charset="utf-8",u.config=function(a){for(var b in a){var c=a[b],d=v[b];if(d&&w(d))for(var e in c)d[e]=c[e];else y(d)?c=d.concat(c):"base"===b&&("/"!==c.slice(-1)&&(c+="/"),c=l(c)),v[b]=c}return D("config",a),u}}}(this);
\ No newline at end of file
This diff is collapsed.
......@@ -46,9 +46,6 @@ export const getEnvironmentData = async (): Promise<any> => await axios.get('/ho
// 获取在线数据接口
export const getOnlineData = async (): Promise<any> => await axios.get('/home/online/data');
// 获取车辆日志列表接口
export const getCarLogList = async (): Promise<any> => await axios.get('home/car/log');
// export const getOnlineAlarmList = async (): Promise<any> => await axios.get('/home/online/alarm/list');
// export const getOnlineAlarmList = async (): Promise<any> => await axios.get('/home/online/alarm/list');
// export const getOnlineAlarmList = async (): Promise<any> => await axios.get('/home/online/alarm/list');
......
......@@ -165,8 +165,7 @@ export const getPointAllPersonApi = async (): Promise<any> => await axios.get(`/
// 查询人员轨迹
export const getPersonPointApi = async (data:any): Promise<any> => await axios.post(`/person/point/trajectory`,data);
// 查询车辆轨迹
export const getCarPointApi = async (data:any): Promise<any> => await axios.post(`/car/point/trajectory`,data);
// ------------------- 越界开采报警接口 ------------------
export const getFencePageApi = async (data:any): Promise<any> => await axios.get(`/fence/log/page?pageNum=${data.pageNum}&pageSize=${data.pageSize}&username=${data.username}&carNumber=${data.carNumber}&startTime=${data.startTime}&endTime=${data.endTime}`);
......@@ -177,8 +176,23 @@ export const putFenceeLogApi = async (data:any): Promise<any> => await axios.put
export const delFenceLogApi = async (ids:any): Promise<any> => await axios.delete(`/fence/log/${ids}`,);
// 大屏卡车位置信息
export const getCarPointAllCarApi = async (): Promise<any> => await axios.get(`/car/point/all/car/location`,);
//
// 大屏信息
export const getCarPointAllCarApi = async (): Promise<any> => await axios.get(`/car/point/all/car/location`);
export const getHomeCarApi = async (carNumber:any): Promise<any> => await axios.get(`/home/car/${carNumber}`);
export const getCemeraPointApi = async (): Promise<any> => await axios.get(`/home/camera/point`);
export const getCameraIdApi = async (id:any): Promise<any> => await axios.get(`/home/camera/${id}`);
export const getMonitorPointApi = async (): Promise<any> => await axios.get(`/home/monitor/point`);
export const getMonitorIdApi = async (id:any): Promise<any> => await axios.get(`/home/monitor/${id}`);
// 卡调
export const getCarPointCarNumberApi = async (): Promise<any> => await axios.get(`/car/point/carNumber`,);
// 查询车辆轨迹
export const getCarPointApi = async (data:any): Promise<any> => await axios.post(`/car/point/trajectory`,data);
// 摄像头
export const getPointListApi = async (): Promise<any> => await axios.get(`/cameras/point/list`,);
export function carSpeed(data:any) {
// 路程
let totalDistance = 0;
// 时间
let totalTimeMs = 0;
for (let i = 0; i < data.points.length - 1; i++) {
const point1 = Cesium.Cartesian3.fromDegrees(data.points[i].lon, data.points[i].lat);
const point2 = Cesium.Cartesian3.fromDegrees(data.points[i + 1].lon, data.points[i + 1].lat);
totalDistance += Cesium.Cartesian3.distance(point1, point2);
const time1 = new Date(data.points[i].createTime).getTime();
const time2 = new Date(data.points[i + 1].createTime).getTime();
const timeDiff = Math.abs(time2 - time1); // 使用绝对值确保时间为正
totalTimeMs += timeDiff;
}
const totalTimeHours = totalTimeMs / (1000 * 60 * 60); // 转换为小时
const totalDistanceKm = totalDistance / 1000;
// 平均时速 (公里/小时)
const averageSpeed = totalTimeHours > 0 ? totalDistanceKm / totalTimeHours : 0;
return averageSpeed;
}
\ No newline at end of file
This diff is collapsed.
......@@ -94,7 +94,6 @@ export async function getElevationFromRay(cartographic: any, viewer: any) {
// 创建红色线
export function createPolyLine(positions: any, viewer: any) {
console.log(positions);
line.value = viewer.entities.add({
name: 'polyline',
polyline: {
......@@ -182,39 +181,16 @@ function densifyPoints(positions: any[], stepSize: number = 2.0) {
return densified;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// ✅ 核心改进 1:路径加密
// 先把只有几个顶点的折线,变成几百个密集的点
// 这样每个点都能去探测模型高度,车子就能贴合起伏了
// =========================================================
const denseCoordinates = densifyPoints(rawCoordinates, 2.0); // 每隔2米插入一个点
export async function createNewPositionHeight(position: any, viewer: any) {
const denseCoordinates = densifyPoints(position, 10.0); // 每隔2米插入一个点
let clampedPositions: any[] = [];
try {
// =========================================================
// ✅ 核心改进 2:批量计算高度
// 现在计算的是加密后那几百个点的高度
// =========================================================
// 提示:clampToHeightMostDetailed 支持的点的数量有限,
// 如果路线非常非常长(几十公里),可能需要分段计算,但一般几千个点没问题。
const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);
clampedPositions = updatedPositions.map((pos: any) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos);
// 💡 稍微抬高 0.5 - 1.0 米,防止车轮半截入土
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 0.8);
});
} catch (error) {
......@@ -222,6 +198,22 @@ export async function startVehicleMovement(viewer: any, totalDuration: number) {
clampedPositions = denseCoordinates;
}
return clampedPositions;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// 下面的逻辑和之前一样,构建 SampledProperty
// =========================================================
......@@ -229,20 +221,21 @@ export async function startVehicleMovement(viewer: any, totalDuration: number) {
const positionProperty = new Cesium.SampledPositionProperty();
let totalDistance = 0;
for (let i = 0; i < clampedPositions.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(clampedPositions[i], clampedPositions[i + 1]);
for (let i = 0; i < rawCoordinates.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(rawCoordinates[i], rawCoordinates[i + 1]);
}
let accumulatedTime = 0;
positionProperty.addSample(viewer.clock.currentTime, clampedPositions[0]);
positionProperty.addSample(viewer.clock.currentTime, rawCoordinates[0]);
for (let i = 1; i < clampedPositions.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(clampedPositions[i - 1], clampedPositions[i]);
for (let i = 1; i < rawCoordinates.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(rawCoordinates[i - 1], rawCoordinates[i]);
const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
accumulatedTime += segmentDuration;
const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
positionProperty.addSample(time, clampedPositions[i]);
positionProperty.addSample(time, rawCoordinates[i]);
}
// 因为点很密集,线性插值(LinearApproximation)其实比 Hermite 更稳,不容易出现“过冲”导致的抖动
......
This diff is collapsed.
......@@ -94,7 +94,6 @@ export async function getElevationFromRay(cartographic: any, viewer: any) {
// 创建红色线
export function createPolyLine(positions: any, viewer: any) {
console.log(positions);
line.value = viewer.entities.add({
name: 'polyline',
polyline: {
......@@ -119,11 +118,11 @@ export function cleanLine(viewer: any, positions: any) {
export function createModel(positions: any, viewer: any) {
if (positions.length == 0) {
message.error('没有数据');
message.error('这个时间点没有数据');
return;
}
const url = '/src/assets/imgs/person1.glb';
const url = '/src/assets/imgs/person2.glb';
const startPoint = positions[0];
if (modelExtiti) {
......@@ -182,46 +181,39 @@ function densifyPoints(positions: any[], stepSize: number = 2.0) {
return densified;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// ✅ 核心改进 1:路径加密
// 先把只有几个顶点的折线,变成几百个密集的点
// 这样每个点都能去探测模型高度,车子就能贴合起伏了
// =========================================================
const denseCoordinates = densifyPoints(rawCoordinates, 2.0); // 每隔2米插入一个点
export async function createNewPositionHeight(position: any, viewer: any) {
const denseCoordinates = densifyPoints(position, 20.0); // 每隔2米插入一个点
let clampedPositions: any[] = [];
try {
// =========================================================
// ✅ 核心改进 2:批量计算高度
// 现在计算的是加密后那几百个点的高度
// =========================================================
// 提示:clampToHeightMostDetailed 支持的点的数量有限,
// 如果路线非常非常长(几十公里),可能需要分段计算,但一般几千个点没问题。
const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);
clampedPositions = updatedPositions.map((pos: any) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos);
// 💡 稍微抬高 0.5 - 1.0 米,防止车轮半截入土
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 0.8);
return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 6);
});
} catch (error) {
console.warn('高度贴合计算失败或部分失败:', error);
clampedPositions = denseCoordinates;
}
return clampedPositions;
}
export async function startVehicleMovement(viewer: any, totalDuration: number) {
// 1. 重置
viewer.clock.currentTime = Cesium.JulianDate.now();
viewer.clock.shouldAnimate = false;
viewer.clock.multiplier = 1;
const trail = line.value;
if (!trail || !trail.polyline || !trail.polyline.positions) return;
const rawCoordinates = trail.polyline.positions.getValue();
if (!rawCoordinates || rawCoordinates.length === 0) return;
// =========================================================
// 下面的逻辑和之前一样,构建 SampledProperty
// =========================================================
......@@ -229,20 +221,21 @@ export async function startVehicleMovement(viewer: any, totalDuration: number) {
const positionProperty = new Cesium.SampledPositionProperty();
let totalDistance = 0;
for (let i = 0; i < clampedPositions.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(clampedPositions[i], clampedPositions[i + 1]);
for (let i = 0; i < rawCoordinates.length - 1; i++) {
totalDistance += Cesium.Cartesian3.distance(rawCoordinates[i], rawCoordinates[i + 1]);
}
let accumulatedTime = 0;
positionProperty.addSample(viewer.clock.currentTime, clampedPositions[0]);
positionProperty.addSample(viewer.clock.currentTime, rawCoordinates[0]);
for (let i = 1; i < clampedPositions.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(clampedPositions[i - 1], clampedPositions[i]);
for (let i = 1; i < rawCoordinates.length; i++) {
const segmentDistance = Cesium.Cartesian3.distance(rawCoordinates[i - 1], rawCoordinates[i]);
const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
accumulatedTime += segmentDuration;
const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
positionProperty.addSample(time, clampedPositions[i]);
positionProperty.addSample(time, rawCoordinates[i]);
}
// 因为点很密集,线性插值(LinearApproximation)其实比 Hermite 更稳,不容易出现“过冲”导致的抖动
......
import { ref } from 'vue';
import { getPointAllPersonApi } from '@/api';
import bluePersonIcon from '@/assets/blueperson.png';
import { getElevationFromRays } from '../cesiumUtil';
let personEntity: any;
const iconEntities = ref<any[]>([]);
const pins: any = [];
// 点位图标
export async function iconPoint(viewer: any, pins: any) {
// // 批量移除实体
iconEntities.value.forEach(item => {
viewer.entities.remove(item.labelExtity);
viewer.entities.remove(item.entity);
});
for (const item of pins) {
if (item.entity) {
viewer.entities.remove(item.entity);
}
const cartographic = Cesium.Cartographic.fromDegrees(item.position.lon, item.position.lat);
const height = await getElevationFromRays(cartographic, viewer);
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height);
item.entity = viewer.entities.add({
position: cartesian,
billboard: {
image: item.image,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: item.type
}
});
allEntities.push(item.entity);
const entity = viewer.entities.add({
position: cartesian,
billboard: {
image: new URL('../../../assets/titlePerson.png', import.meta.url).href,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -30), // 位置在图标上方
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: item.type
}
});
entity.billboard.width = 220; // 直接设置宽度
entity.billboard.height = 50; // 直接设置高度
allEntities.push(entity);
// 创建名字标签实体
const labelEntit = viewer.entities.add({
position: cartesian,
label: {
text: item.name,
font: 'bold 14px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(0, -36), // 位置在标签框上方
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
scaleByDistance: new Cesium.NearFarScalar(1000, 1, 5000, 0.5),
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000)
},
properties: {
type: item.type
}
});
allEntities.push(labelEntit);
iconEntities.value.push({
labelExtity: labelEntit,
entity
});
}
return { pins, allEntities };
}
......@@ -7,66 +7,37 @@ let personEntity: any;
const iconEntities = ref<any[]>([]);
const pins: any = [];
// 点位图标
export async function iconPoint(viewer: any, data: any, type: any) {
console.log('--1--', data);
const typeIcons = {
person_: new URL('@/assets/blueperson.png', import.meta.url).href,
car_: new URL('@/assets/icon15.png', import.meta.url).href,
slope_: new URL('@/assets/icon17.png', import.meta.url).href,
default: new URL('@/assets/blueperson.png', import.meta.url).href
};
// 清除所有以当前type前缀开头的实体,确保每次调用都是全新的
const entitiesToRemove: any[] = [];
viewer.entities.values.forEach((entity: any) => {
if (typeof entity.id === 'string' && entity.id.startsWith(type)) {
entitiesToRemove.push(entity);
}
export async function iconPoint(viewer: any, pins: any) {
// // 批量移除实体
iconEntities.value.forEach(item => {
viewer.entities.remove(item.labelExtity);
viewer.entities.remove(item.entity);
});
// 批量移除实体
entitiesToRemove.forEach(entity => viewer.entities.remove(entity));
for (const item of pins) {
if (item.entity) {
viewer.entities.remove(item.entity);
}
const cartographic = Cesium.Cartographic.fromDegrees(item.position.lon, item.position.lat);
for (let i = 0; i < data.value.length; i++) {
const cartographic = Cesium.Cartographic.fromDegrees(data.value[i].lon, data.value[i].lat);
const height = await getElevationFromRays(cartographic, viewer);
// 将高度增加一些,确保标签和图标在地形上方
const adjustedHeight = height + 1;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
const iconPath = typeIcons[type as keyof typeof typeIcons] || typeIcons.default;
// 创建实体ID使用传入的type前缀
const entityId = `${type}${i}`;
const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height);
// 检查是否已存在相同ID的实体,如果存在则移除
const existingEntity = viewer.entities.getById(entityId);
if (existingEntity) {
viewer.entities.remove(existingEntity);
}
// 创建人员/车辆图标实体
personEntity = viewer.entities.add({
id: entityId, // 使用传入的type前缀确保唯一性
item.entity = viewer.entities.add({
position: cartesian,
billboard: {
image: iconPath,
image: item.image,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
scale: 0.5,
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: data.value[i].type
},
// 存储人员数据
personData: {
index: i,
info: data.value[i]
type: item.type
}
});
// 创建标签框背景实体
const entity = viewer.entities.add({
position: cartesian,
billboard: {
......@@ -76,9 +47,6 @@ export async function iconPoint(viewer: any, data: any, type: any) {
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -30), // 位置在图标上方
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND
},
properties: {
type: data.value[i].type
}
});
entity.billboard.width = 220; // 直接设置宽度
......@@ -88,7 +56,7 @@ export async function iconPoint(viewer: any, data: any, type: any) {
const labelEntit = viewer.entities.add({
position: cartesian,
label: {
text: data.value[i].carNumber || data.value[i].realName,
text: item.name,
font: 'bold 14px sans-serif',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
......@@ -100,23 +68,17 @@ export async function iconPoint(viewer: any, data: any, type: any) {
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
scaleByDistance: new Cesium.NearFarScalar(1000, 1, 5000, 0.5),
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000)
},
properties: {
type: data.value[i].type
}
});
iconEntities.value.push(personEntity, entity, labelEntit);
// 存储标签实体到pins数组中,以便主组件控制显示隐藏
item.labelEntity = labelEntit;
item.backgroundEntity = entity;
pins.push({
entity: personEntity,
cardId: data.value[i].cardId,
type: personEntity.id,
position: cartesian,
label: null,
data: data.value[i]
iconEntities.value.push({
labelExtity: labelEntit,
entity
});
}
return pins;
}
src/assets/blueperson.png

1.69 KB | W: | H:

src/assets/blueperson.png

1.76 KB | W: | H:

src/assets/blueperson.png
src/assets/blueperson.png
src/assets/blueperson.png
src/assets/blueperson.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jinrun/bg-left.png

219 KB | W: | H:

src/assets/jinrun/bg-left.png

233 KB | W: | H:

src/assets/jinrun/bg-left.png
src/assets/jinrun/bg-left.png
src/assets/jinrun/bg-left.png
src/assets/jinrun/bg-left.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jinrun/bg-right.png

219 KB | W: | H:

src/assets/jinrun/bg-right.png

233 KB | W: | H:

src/assets/jinrun/bg-right.png
src/assets/jinrun/bg-right.png
src/assets/jinrun/bg-right.png
src/assets/jinrun/bg-right.png
  • 2-up
  • Swipe
  • Onion skin
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment