Compare commits
38 Commits
e8d98f155d
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| b731c31241 | |||
| 382a5f6c34 | |||
| f99647775c | |||
| 90b1fe2f7a | |||
| c414e66e2b | |||
| 77ed33e66c | |||
| a41a611975 | |||
| 4d067e62ea | |||
| 5104d09674 | |||
| 7efa0e210b | |||
| 2492e4b650 | |||
| c9f4412f89 | |||
| d111649c41 | |||
| a3cf0f610e | |||
| e5bf2d35cd | |||
| 78c34a0e57 | |||
| 353ff3353e | |||
| 978dcf8abf | |||
| 023dd01e29 | |||
| 5279134836 | |||
| bd5fac5ec8 | |||
| 8c594933b9 | |||
| 8e72b0b12c | |||
| e52359f321 | |||
| 9ccfe6c75f | |||
| cb1d44f616 | |||
| 7ccd30e3c7 | |||
| ca18d29829 | |||
| 781361acd5 | |||
| c45fc5d7b3 | |||
| a2033b2132 | |||
| d7c7acb018 | |||
| 94336c9ba1 | |||
| fb037dbf6f | |||
| 8820b28ab8 | |||
| 62a5415e97 | |||
| 9e8566d158 | |||
| 4c6b3fc4d7 |
5
.gitignore
vendored
@ -22,11 +22,10 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
/myis11/project/is11/cmake-build-debug-visual-studio-2022/
|
||||
/myis11/project/is11/cmake-build-release-visual-studio-2022/
|
||||
|
||||
/myis11/project/*/cmake-build-*
|
||||
/myis11/project/is11/vscode/
|
||||
/myis11/.vscode/
|
||||
/myis11/.cmake/
|
||||
/.vscode/
|
||||
/src-tauri/.cargo/
|
||||
/.vscode/
|
||||
|
||||
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "myis11/src/thirdpart/iris_proto_tool"]
|
||||
path = myis11/src/thirdpart/iris_proto_tool
|
||||
url = http://172.16.0.230:3000/xin/IRIS_Communication_Protocol.git
|
||||
12
.roo/mcp.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"filesystem": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-filesystem",
|
||||
"./"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
3
doc/数据查看前端文档.md
Normal file
@ -0,0 +1,3 @@
|
||||
1 函数 invoke("getoneirisfile",{path:"iris_data_example.iris"}) 返回一次数据
|
||||
|
||||
2 fs
|
||||
BIN
myis11/doc/IS3通讯协议.pdf
Normal file
@ -7,8 +7,12 @@ if (MSVC)
|
||||
|
||||
endif()
|
||||
include_directories(../../src/test)
|
||||
include_directories(../../src/IRIS_IS3)
|
||||
include_directories(../../src/comman)
|
||||
include_directories(../../src/is11)
|
||||
|
||||
add_library(is11lib SHARED
|
||||
|
||||
../../src/test/test.cpp
|
||||
../../src/is11/SensorIS11.cpp
|
||||
../../src/is11/SensorIS11.h
|
||||
@ -18,6 +22,8 @@ add_library(is11lib SHARED
|
||||
../../src/is11/IS11_INST.h
|
||||
|
||||
)
|
||||
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
|
||||
|
||||
45
myis11/project/is3/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
#vcpkg config
|
||||
if (MSVC)
|
||||
set(CMAKE_TOOLCHAIN_FILE "E:/01MyCode/vcpkg/vcpkgclion/scripts/buildsystems/vcpkg.cmake")
|
||||
endif()
|
||||
project(is11lib)
|
||||
|
||||
|
||||
|
||||
if (MSVC)
|
||||
find_package(cserialport REQUIRED)
|
||||
# 静态链接多线程版本的运行时库
|
||||
set(CMAKE_CXX_FLAGS "/MT")
|
||||
set(CMAKE_C_FLAGS "/MT")
|
||||
include_directories(${CSerialPort_INCLUDE_DIR})
|
||||
message(STATUS "CSerialPort_INCLUDE_DIR: ${CSerialPort_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
include_directories(../../src/test)
|
||||
include_directories(../../src/IRIS_IS3)
|
||||
include_directories(../../src/comman)
|
||||
include_directories(../../src/thirdpart/iris_proto_tool/src)
|
||||
add_library(iris_is3lib SHARED
|
||||
../../src/thirdpart/iris_proto_tool/src/IRIS_Method.cpp
|
||||
../../src/IRIS_IS3/SensorIS3.cpp
|
||||
../../src/IRIS_IS3/IS3_INST.cpp
|
||||
../../src/IRIS_IS3/IS3Comon.cpp
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
if (MSVC)
|
||||
add_executable(is3test
|
||||
testmain.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(is3test iris_is3lib ${CSerialPort_LIBRARY})
|
||||
message(STATUS "CSerialPort_LIBRARY: ${CSerialPort_LIBRARY}")
|
||||
|
||||
#add_executable(is11test
|
||||
# testmain.cpp
|
||||
#)
|
||||
endif()
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
129
myis11/project/is3/testmain.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : testmain.cpp
|
||||
* @author : xin
|
||||
* @brief : None
|
||||
* @attention : None
|
||||
* @date : 2024/8/14
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "IS3_INST.h"
|
||||
#include "CSerialPort/SerialPort.h"
|
||||
#include "CSerialPort/SerialPortInfo.h"
|
||||
#include "stdio.h"
|
||||
#include "vector"
|
||||
using namespace itas109;
|
||||
CSerialPort *serialport;
|
||||
|
||||
size_t SerialWrite(u_char* data,size_t lenth)
|
||||
{
|
||||
printf("write data:");
|
||||
for (int i = 0; i < lenth; ++i) {
|
||||
printf("%02x ",data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
serialport->flushReadBuffers();
|
||||
return serialport->writeData(data,lenth);
|
||||
|
||||
|
||||
|
||||
}
|
||||
size_t SerailRead(u_char* data,size_t lenth)
|
||||
{
|
||||
|
||||
|
||||
size_t lenthread=serialport->readData(data,lenth);
|
||||
// printf("read data:");
|
||||
// for (int i = 0; i < lenthread; ++i)
|
||||
// {
|
||||
// printf("%02x ",data[i]);
|
||||
// }
|
||||
// printf("\n");
|
||||
|
||||
|
||||
|
||||
// printf("read data: %d\n",lenthread);
|
||||
// int indexnow=serialport->getReadBufferUsedLen();
|
||||
|
||||
// printf("read data index: %d\n",indexnow);
|
||||
//fflush(stdout);
|
||||
|
||||
return lenthread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
serialport = new CSerialPort();
|
||||
//获取串口列表
|
||||
|
||||
std::vector<SerialPortInfo> portNameList = CSerialPortInfo::availablePortInfos();
|
||||
for (int i = 0; i < portNameList.size(); ++i) {
|
||||
printf("portName:%s\n",portNameList[i].portName);
|
||||
}
|
||||
std::string portname="COM24";
|
||||
serialport->init(portname.c_str(),BaudRate921600 ,ParityNone,DataBits8,StopOne,FlowNone,512*512);
|
||||
serialport->setOperateMode(SynchronousOperate);
|
||||
//serialport->setReadIntervalTimeout(10000);
|
||||
if (serialport->open())
|
||||
{ printf("open success\n");
|
||||
}else {
|
||||
printf("open fail \n may be port: %s is busy or not exist\n",portname.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// IS11SensorInit();
|
||||
printf("Hello World\n");
|
||||
IS3Set_Serial_FUN(SerialWrite,SerailRead);
|
||||
IS3SensorInit();
|
||||
uint16_t *buffforread=new uint16_t[1000];
|
||||
// while (1) {
|
||||
// IS3SetShutterOpen(0);
|
||||
// IS3GetData(buffforread,1000);
|
||||
// IS3SetShutterOpen(1);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
STRsensorinfo_C info= IS3Get_SensorInfo();
|
||||
//输出info
|
||||
printf("--------------------------------------\nSensorName:%s\n",info.SensorName);
|
||||
printf("serialnumber:%s\n",info.serialnumber);
|
||||
printf("maxValue:%d\n",info.maxValue);
|
||||
printf("a1:%f\n",info.a1);
|
||||
printf("a2:%f\n",info.a2);
|
||||
printf("a3:%f\n",info.a3);
|
||||
printf("a4:%f\n",info.a4 );
|
||||
double a[4]={0.0,0.001,1,350};
|
||||
IS3SetWeaveLenthCoeff(a,4);
|
||||
info= IS3Get_SensorInfo();
|
||||
//输出info
|
||||
printf("SensorName:%s\n",info.SensorName);
|
||||
printf("serialnumber:%s\n",info.serialnumber);
|
||||
printf("maxValue:%d\n",info.maxValue);
|
||||
printf("a1:%f\n",info.a1);
|
||||
printf("a2:%f\n",info.a2);
|
||||
printf("a3:%f\n",info.a3);
|
||||
printf("a4:%f\n",info.a4 );
|
||||
|
||||
IS3OptSnenser(80);
|
||||
while (1) {
|
||||
IS3GetData(buffforread,200);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Created by xin on 2024/8/14.
|
||||
//
|
||||
336
myis11/src/IRIS_IS3/IS3Comon.cpp
Normal file
@ -0,0 +1,336 @@
|
||||
#include "IS3Comon.h"
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
void delay(int ms){
|
||||
Sleep(ms);
|
||||
}
|
||||
#else
|
||||
#include <unistd.h> // For usleep
|
||||
|
||||
void delay(int ms){
|
||||
usleep(ms * 1000); // Convert milliseconds to microseconds
|
||||
}
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#endif
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include <Communication_Protocol.h>
|
||||
|
||||
unsigned long long get_system_uptime_ms() {
|
||||
#ifdef _WIN32
|
||||
return GetTickCount64();
|
||||
|
||||
#else
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (unsigned long long)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
u_char BufferForRead[10000];
|
||||
int TotalIndexNow = 0;
|
||||
u_char BufferFortempWrite[1000];
|
||||
// MySerialWrite=nullptr;
|
||||
SERIALWRITE MySerialWrite = nullptr;
|
||||
SERIALREAD MySerialRead = nullptr;
|
||||
bool isIS3Init = false;
|
||||
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial)
|
||||
{
|
||||
uint16_t i, j, tmp, CRC16;
|
||||
|
||||
CRC16 = 0xFFFF; // CRC<52>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ʼֵ
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
CRC16 ^= data[i];
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
tmp = (uint16_t)(CRC16 & 0x0001);
|
||||
CRC16 >>= 1;
|
||||
if (tmp == 1)
|
||||
{
|
||||
CRC16 ^= polynomial; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
||||
}
|
||||
}
|
||||
}
|
||||
return CRC16;
|
||||
}
|
||||
|
||||
size_t SendSettingCommand(u_char Command, size_t CommandLenth, u_char *Value, size_t ValueLenth)
|
||||
{
|
||||
|
||||
int lenthforwrite = IRIS_Protocol_Pack(Command, (uint16_t)ValueLenth, Value, (uint8_t *)BufferFortempWrite);
|
||||
SerialWrite(BufferFortempWrite, lenthforwrite);
|
||||
// for 5 <20><>
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
size_t retunnumber = GetInfoBackFromSensorinTime(Command,1000);
|
||||
if (retunnumber!=OVERTIME ) {
|
||||
return retunnumber;
|
||||
}
|
||||
if (i%2==0) {
|
||||
printf("send command again\n");
|
||||
SerialWrite(BufferFortempWrite, lenthforwrite);
|
||||
|
||||
}
|
||||
|
||||
// <20><>I<EFBFBD>γ<EFBFBD><CEB3><EFBFBD> <20><><EFBFBD>ݻظ<DDBB><D8B8>쳣 <20><><EFBFBD><EFBFBD>ȷʵ <20><>Ӣ<EFBFBD>Ĵ<EFBFBD>ӡ
|
||||
printf("warning try %d times: date not enough,try again!!\n",i);
|
||||
|
||||
|
||||
}
|
||||
|
||||
printf("ERROR date not enough,retunr !!\n");
|
||||
return OVERTIME;
|
||||
|
||||
|
||||
}
|
||||
|
||||
size_t SendGetData(int shutter)
|
||||
{
|
||||
uint8_t dataforsend=NONE_DATA;
|
||||
int lenthforwrite=IRIS_Protocol_Pack(GET_DATA_FROM_SENSOR, (uint16_t)01, &dataforsend, (uint8_t *)BufferFortempWrite );
|
||||
|
||||
SerialWrite(BufferFortempWrite, lenthforwrite);
|
||||
for (int i=0;i<10;i++)
|
||||
{
|
||||
size_t retunnumber = GetInfoBackFromSensorinTime(GET_DATA_FROM_SENSOR,3*shutter);
|
||||
//size_t retunnumber = GetInfoBackFromSensorinTime(GET_DATA_FROM_SENSOR,2*shutter+2000);
|
||||
if (retunnumber<OVERTIME) {
|
||||
return retunnumber;
|
||||
}
|
||||
if (i%2==0) {
|
||||
printf("send command again\n");
|
||||
SerialWrite(BufferFortempWrite, lenthforwrite);
|
||||
|
||||
}
|
||||
// <20><>I<EFBFBD>γ<EFBFBD><CEB3><EFBFBD> <20><><EFBFBD>ݻظ<DDBB><D8B8>쳣 <20><><EFBFBD><EFBFBD>ȷʵ <20><>Ӣ<EFBFBD>Ĵ<EFBFBD>ӡ
|
||||
printf("warning try %d times: date not enough,try again!!\n",i);
|
||||
}
|
||||
|
||||
// size_t retunnumber = GetInfoBackFromSensor(GET_DATA_FROM_SENSOR);
|
||||
|
||||
|
||||
return OVERTIME;
|
||||
}
|
||||
|
||||
size_t SendGetSensorInfo(u_char Command, size_t lenth)
|
||||
{
|
||||
uint8_t dataforsend=NONE_DATA;
|
||||
|
||||
int lenthforwrite= IRIS_Protocol_Pack(Command,(uint16_t)01,&dataforsend,(uint8_t *)BufferFortempWrite);
|
||||
|
||||
|
||||
//delay(200);
|
||||
SerialWrite(BufferFortempWrite, lenthforwrite);
|
||||
|
||||
size_t retunnumber = GetInfoBackFromSensor(Command);
|
||||
|
||||
return retunnumber;
|
||||
}
|
||||
|
||||
size_t GetSetBackFromSensor()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t GetInfoBackFromSensor(uint8_t Command) // big <20><>ָ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>ֽڱ<D6BD>ʾ<EFBFBD><CABE><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><>ʱֻ<CAB1><D6BB><EFBFBD>ֲɼ<D6B2><C9BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
{
|
||||
delay(1);
|
||||
TotalIndexNow = 0;
|
||||
BufferForRead[0] = 0x00;
|
||||
memset(BufferForRead, 0, 200);
|
||||
|
||||
|
||||
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 2);
|
||||
|
||||
|
||||
TotalIndexNow += retrunlenth;
|
||||
// TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
|
||||
while (TotalIndexNow<5) {
|
||||
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 5-TotalIndexNow);
|
||||
TotalIndexNow += retrunlenth;
|
||||
// if (retrunlenth!=0) {
|
||||
// //<2F><><EFBFBD>bufferforread
|
||||
// for (int i = 0; i < TotalIndexNow; i++) {
|
||||
// printf("%02x ", BufferForRead[i]);
|
||||
// }
|
||||
// printf("here3 %d\n",retrunlenth);
|
||||
// fflush(stdout);
|
||||
// }
|
||||
TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
|
||||
|
||||
// if (retrunlenth!=10) {
|
||||
// delay(1000);
|
||||
// }
|
||||
}
|
||||
int lenth = BufferForRead[3] * 256 + BufferForRead[4];
|
||||
while (TotalIndexNow < lenth + 7)
|
||||
{
|
||||
int sizeread=SerailRead(BufferForRead + TotalIndexNow, 10);
|
||||
//printf("Data from sensor: %d\n",sizeread);
|
||||
TotalIndexNow +=sizeread;
|
||||
if (sizeread!=10) {
|
||||
//delay(10);
|
||||
}
|
||||
//delay(10);
|
||||
//delay(10);
|
||||
}
|
||||
// <20><><EFBFBD>bufferforread
|
||||
printf("Data from sensor: ");
|
||||
int maxoutput= TotalIndexNow>50 ? 50 : TotalIndexNow;
|
||||
for (int i = 0; i <maxoutput; i++) {
|
||||
printf("%02x ", BufferForRead[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
TotalIndexNow= IRIS_Protocol_Unpack(BufferForRead,TotalIndexNow,Command,BufferForRead);
|
||||
return TotalIndexNow;
|
||||
|
||||
}
|
||||
|
||||
#include <chrono>
|
||||
|
||||
size_t GetInfoBackFromSensorinTime(uint8_t Command,uint32_t waittime) // big <20><>ָ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>ֽڱ<D6BD>ʾ<EFBFBD><CABE><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><>ʱֻ<CAB1><D6BB><EFBFBD>ֲɼ<D6B2><C9BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
{
|
||||
// delay(1);
|
||||
//<2F><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
size_t begintime= get_system_uptime_ms();
|
||||
|
||||
TotalIndexNow = 0;
|
||||
BufferForRead[0] = 0x00;
|
||||
memset(BufferForRead, 0, 200);
|
||||
|
||||
|
||||
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 2);
|
||||
|
||||
|
||||
TotalIndexNow += retrunlenth;
|
||||
// TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
|
||||
while (TotalIndexNow<5) {
|
||||
size_t retrunlenth=SerailRead(BufferForRead + TotalIndexNow, 5-TotalIndexNow);
|
||||
TotalIndexNow += retrunlenth;
|
||||
// if (retrunlenth!=0) {
|
||||
// //<2F><><EFBFBD>bufferforread
|
||||
// for (int i = 0; i < TotalIndexNow; i++) {
|
||||
// printf("%02x ", BufferForRead[i]);
|
||||
// }
|
||||
// printf("here3 %d\n",retrunlenth);
|
||||
// fflush(stdout);
|
||||
// }
|
||||
TotalIndexNow=IRIS_Cut_Befor_Header(BufferForRead,TotalIndexNow);
|
||||
if (get_system_uptime_ms()-begintime>waittime) return OVERTIME;
|
||||
// if (retrunlenth!=10) {
|
||||
// delay(1000);
|
||||
// }
|
||||
}
|
||||
if (BufferForRead[2]==0x40) {
|
||||
printf("warning: sensor busy\n");
|
||||
return SENSORBUSY;
|
||||
|
||||
}
|
||||
int lenth = BufferForRead[3] * 256 + BufferForRead[4];
|
||||
while (TotalIndexNow < lenth + 7)
|
||||
{
|
||||
int sizeread=SerailRead(BufferForRead + TotalIndexNow, 10);
|
||||
//printf("Data from sensor: %d\n",sizeread);
|
||||
TotalIndexNow +=sizeread;
|
||||
if (sizeread!=10) {
|
||||
//delay(10);
|
||||
}
|
||||
if (get_system_uptime_ms()-begintime>waittime) return OVERTIME;
|
||||
//delay(10);
|
||||
//delay(10);
|
||||
}
|
||||
// <20><><EFBFBD>bufferforread
|
||||
printf("Data from sensor: ");
|
||||
int maxoutput= TotalIndexNow>50 ? 50 : TotalIndexNow;
|
||||
for (int i = 0; i <maxoutput; i++) {
|
||||
printf("%02x ", BufferForRead[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
TotalIndexNow= IRIS_Protocol_Unpack(BufferForRead,TotalIndexNow,Command,BufferForRead);
|
||||
return TotalIndexNow;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
size_t SerialWrite(u_char *data, size_t lenth)
|
||||
{
|
||||
if (MySerialWrite != nullptr)
|
||||
{
|
||||
// Serial.println("init ok");
|
||||
return MySerialWrite(data, lenth);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t SerailRead(u_char *data, size_t lenth)
|
||||
{
|
||||
if (MySerialRead != nullptr)
|
||||
{
|
||||
size_t aa= MySerialRead(data, lenth);
|
||||
|
||||
return aa;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitFunction(SERIALWRITE a, SERIALWRITE readfunc)
|
||||
{
|
||||
MySerialWrite = a;
|
||||
MySerialRead = readfunc;
|
||||
//std::string temp = "01";
|
||||
//a((u_char *)temp.c_str(), 2);
|
||||
isIS3Init = true;
|
||||
}
|
||||
|
||||
u_char *GetDataBufferPTR()
|
||||
{
|
||||
return BufferForRead;
|
||||
}
|
||||
bool isSensorInit()
|
||||
{
|
||||
return isIS3Init;
|
||||
}
|
||||
|
||||
void CoverLittleAndBig(char *data, int lenth)
|
||||
{
|
||||
char *tempdata = new char[lenth];
|
||||
memcpy(tempdata, data, lenth);
|
||||
|
||||
for (size_t i = 0; i < lenth / 2; i++)
|
||||
{
|
||||
data[2 * i] = tempdata[2 * i + 1];
|
||||
data[2 * i + 1] = tempdata[2 * i];
|
||||
/* code */
|
||||
}
|
||||
delete[] tempdata;
|
||||
}
|
||||
|
||||
void CoverLittleandBigbyNumber(void *data, int lenth)
|
||||
{
|
||||
char *tempdata = new char[lenth];
|
||||
memcpy(tempdata, data, lenth);
|
||||
for (size_t i = 0; i < lenth ; i++) {
|
||||
((char *)data)[i] = tempdata[lenth-1-i];
|
||||
}
|
||||
delete[] tempdata;
|
||||
|
||||
}
|
||||
145
myis11/src/IRIS_IS3/IS3Comon.h
Normal file
@ -0,0 +1,145 @@
|
||||
|
||||
/**
|
||||
* @brief is11<31><31><EFBFBD>صײ㺯<D7B2><E3BAAF>
|
||||
*
|
||||
*/
|
||||
#ifndef __IS11COMON_H__
|
||||
#define __IS11COMON_H__
|
||||
|
||||
#ifndef IS11COMMON_H
|
||||
#define IS11COMMON_H
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
#define COMMAND_GET 0x03
|
||||
#define COMMAND_SET 0x06
|
||||
#define COMMAND_MULTSET 0x10
|
||||
#define POLYNOMIAL 0xa001 //modbus crc
|
||||
#define OVERTIME 1000000000
|
||||
#define SENSORBUSY 1000000000
|
||||
#include "comon.h"
|
||||
|
||||
|
||||
const u_char GET_ADDRESS[]={0x01,0x03,0x00,0x01,0x00,0x01};
|
||||
const u_char GET_BANDRATE[]={0x01,0x03,0x00,0x02,0x00,0x01};
|
||||
const u_char GET_INTEGRAL_TIME[]={0x01,0x03,0x00,0x06,0x00,0x01};
|
||||
const u_char GET_AVERAGE_NUMBER[]={0x01,0x03,0x00,0x07,0x00,0x01};
|
||||
const u_char GET_WAVELENTH_AT_BAND[]={0x01, 0x03, 0x00,0x10, 0x00,0x02};
|
||||
const u_char GET_VALUE_AT_BAND[]={0x01, 0x03, 0x00,0x30, 0x00,0x02};
|
||||
const u_char GET_SETTING_OF_LAMP[]={0x01, 0x03, 0x00,0x04, 0x00,0x01};
|
||||
// const u_char GET_WAVELENTH_COEFF[]={0x01, 0x03, 0x00,0x20, 0x00,0x08};
|
||||
const u_char GET_ALL_DN[]={0x01, 0x03, 0x01,0x00, 0x10,0x00};
|
||||
const u_char GET_SERIAL_NUMBER[]={0x01, 0x03, 0x00,0x40, 0x00,0x00};
|
||||
const u_char GET_PRODUCT_NAME[]={0x01, 0x03, 0x00,0x50, 0x00,0x00};
|
||||
|
||||
const u_char SET_ADDRESS[]={0x01,0x06, 0x00,0x01};
|
||||
const u_char SET_BandRATE[]={0x01,0x06, 0x00,0x02};
|
||||
const u_char SET_INTEGRAL_TIME[]={0x01,0x06, 0x00,0x06};
|
||||
const u_char SET_AVERAGE_NUMBER[]={0x01,0x06, 0x00,0x07};
|
||||
const u_char SET_WORK_MODE[]={0x01,0x06, 0x00,0x01};
|
||||
const u_char SET_WAVELENTH_COEFF[]={0x01,0x10,0x00,0x20,0x00,0x08,0x16};
|
||||
|
||||
/**
|
||||
* @brief <20>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
bool isSensorInit();
|
||||
/**
|
||||
* @brief <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param writefunc д<><D0B4><EFBFBD><EFBFBD>
|
||||
* @param readfunc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void InitFunction(SERIALWRITE writefunc,SERIALWRITE readfunc);
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ BufferForRead <20><>ָ<EFBFBD><D6B8> <20><><EFBFBD>ڶ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
*/
|
||||
u_char * GetDataBufferPTR();
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD>ͻ<EFBFBD>ȡ<EFBFBD>豸<EFBFBD><E8B1B8>Ϣ<EFBFBD><CFA2>ָ<EFBFBD><D6B8> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Getָ<74><D6B8>
|
||||
*
|
||||
* @param Command ָ<><D6B8> Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param lenth ָ<><EFBFBD><EEB3A4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sizeof<6F><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return size_t <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵij<DDB5><C4B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BufferForRead;
|
||||
*/
|
||||
size_t SendGetSensorInfo(u_char Command,size_t lenth);//<2F>˹<EFBFBD><CBB9>̲<EFBFBD><CCB2>ʺϻ<CABA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param shutter
|
||||
* @return size_t
|
||||
*/
|
||||
size_t SendGetData(int shutter);
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
*
|
||||
* @param Command ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param CommandLenth ָ<><EFBFBD><EEB3A4>
|
||||
* @param Value <20><><EFBFBD><EFBFBD>ֵ
|
||||
* @param ValueLenth ֵ<><D6B5><EFBFBD><EFBFBD> Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
* @return size_t <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
|
||||
*/
|
||||
size_t SendSettingCommand(u_char Command,size_t CommandLenth,u_char *Value,size_t ValueLenth=2);
|
||||
|
||||
//big
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD>ķ<EFBFBD><C4B7>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @param isbig <20><>ָ<EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD>ֽڱ<D6BD>ʾ<EFBFBD><CABE><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><>ʱֻ<CAB1><D6BB><EFBFBD>ֲɼ<D6B2><C9BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
* @return size_t <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>С
|
||||
*/
|
||||
size_t GetInfoBackFromSensor(uint8_t Command);
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1><EFBFBD>ú<C3BA><F3B7B5BB><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @return size_t <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>;
|
||||
*/
|
||||
size_t GetSetBackFromSensor();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param data
|
||||
* @param lenth
|
||||
* @return size_t
|
||||
*/
|
||||
|
||||
size_t SerialWrite(u_char* data,size_t lenth);
|
||||
size_t SerailRead(u_char* data,size_t lenth=0);
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>crc16
|
||||
*
|
||||
* @param data <20><><EFBFBD><EFBFBD>
|
||||
* @param len <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
* @param polynomial crc16<31><36><EFBFBD><EFBFBD>ʽ Ĭ<><C4AC><EFBFBD><EFBFBD>A001H
|
||||
* @return uint16_t crc16<31><36>ֵ
|
||||
*/
|
||||
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial=POLYNOMIAL) ;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Command
|
||||
* @param waittime <20><><EFBFBD><EFBFBD>
|
||||
* @return
|
||||
*/
|
||||
size_t GetInfoBackFromSensorinTime(uint8_t Command,uint32_t waittime=5000);
|
||||
|
||||
|
||||
void CoverLittleAndBig(char *data,int lenth);
|
||||
void CoverLittleandBigbyNumber(void *data, int lenth);
|
||||
#ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif // __IS11COMON_H__
|
||||
84
myis11/src/IRIS_IS3/IS3_INST.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : IS11_INST.cpp
|
||||
* @author : xin
|
||||
* @brief : None
|
||||
* @attention : None
|
||||
* @date : 2024/8/14
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by xin on 2024/8/14.
|
||||
//
|
||||
#include "SensorIS3.h"
|
||||
#include "IS3_INST.h"
|
||||
#include "iostream"
|
||||
#include "cstring"
|
||||
#include <string> // 如果 sensorinfo.SensorName 是 std::string 类型
|
||||
#include <cstdio> // 对于 snprintf
|
||||
SensorIS3 *thissensorIS3;
|
||||
int IS3SensorInit()
|
||||
{
|
||||
std::cout<< "IS3SensorInit" << std::endl;
|
||||
thissensorIS3 = new SensorIS3();
|
||||
thissensorIS3->initSensor(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void IS3Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc)
|
||||
{
|
||||
InitFunction(writefunc,readfunc);
|
||||
}
|
||||
|
||||
STRsensorinfo_C IS3Get_SensorInfo() {
|
||||
STRSensorInfo sensorinfo= thissensorIS3->SensorInfo;
|
||||
STRsensorinfo_C sensorinfo_c;
|
||||
//把sensorname 拷贝到sensorinfo_c
|
||||
snprintf(sensorinfo_c.SensorName, sizeof(sensorinfo_c.SensorName), "%s", sensorinfo.SensorName.c_str());
|
||||
// strcpy_s(sensorinfo_c.SensorName,sensorinfo.SensorName.c_str());
|
||||
sensorinfo_c.BandNum = sensorinfo.BandNum;
|
||||
sensorinfo_c.maxValue = sensorinfo.maxValue;
|
||||
|
||||
//strcpy_s(sensorinfo_c.serialnumber,sensorinfo.serialnumber.c_str());
|
||||
snprintf(sensorinfo_c.serialnumber, sizeof(sensorinfo_c.serialnumber), "%s", sensorinfo.serialnumber.c_str());
|
||||
sensorinfo_c.a1 = sensorinfo.a1;
|
||||
sensorinfo_c.a2 = sensorinfo.a2;
|
||||
sensorinfo_c.a3 = sensorinfo.a3;
|
||||
sensorinfo_c.a4 = sensorinfo.a4;
|
||||
sensorinfo_c.issensorinit= sensorinfo.isSensorInit;
|
||||
return sensorinfo_c;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int IS3OptSnenser(int percent) {
|
||||
return thissensorIS3->OptSnenser(percent);
|
||||
}
|
||||
|
||||
int IS3GetData(uint16_t *outdata, int shuttertime) {
|
||||
thissensorIS3->GetOneDate(shuttertime);
|
||||
memcpy(outdata,thissensorIS3->DATABUFF, sizeof(int16_t)*thissensorIS3->SensorInfo.BandNum);
|
||||
float averageofdrift=(thissensorIS3->DATABUFF[thissensorIS3->SensorInfo.BandNum-1]+thissensorIS3->DATABUFF[thissensorIS3->SensorInfo.BandNum-0]+thissensorIS3->DATABUFF[thissensorIS3->SensorInfo.BandNum+1])/3;
|
||||
// for(int i=0;i<thissensorIS3->SensorInfo.BandNum;i++)
|
||||
// {
|
||||
// outdata[i]-=averageofdrift;
|
||||
// if (outdata[i]<0)
|
||||
// outdata[i]=0;
|
||||
// }
|
||||
return thissensorIS3->SensorInfo.BandNum;
|
||||
|
||||
}
|
||||
int IS3SetWeaveLenthCoeff(double *a,int lenth) {
|
||||
// printf("IS3SetWeaveLenthCoeff\n");
|
||||
// printf("lenth=%d\n",lenth);
|
||||
// printf("a[0]=%f\n",a[0]);
|
||||
thissensorIS3->SetWeaveLenthCoeff(a,lenth);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void IS3SetShutterOpen(int isopen) {
|
||||
thissensorIS3->SetShutter(isopen);
|
||||
// printf("IS3SetShutterOpen\n");
|
||||
// printf("isopen=%d\n",isopen);
|
||||
}
|
||||
40
myis11/src/IRIS_IS3/IS3_INST.h
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : IS3_INST.h
|
||||
* @author : xin
|
||||
* @brief : None
|
||||
* @attention : None
|
||||
* @date : 2024/8/14
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by xin on 2024/8/14.
|
||||
//
|
||||
|
||||
#ifndef IS3LIB_IS3_INST_H
|
||||
#define IS3LIB_IS3_INST_H
|
||||
#include "comon.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WINDOWSEXPORT __declspec(dllexport) // Windows下导出函数
|
||||
#else
|
||||
#define WINDOWSEXPORT // Linux下导出函数
|
||||
#endif
|
||||
|
||||
WINDOWSEXPORT int IS3SensorInit();
|
||||
WINDOWSEXPORT void IS3Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc);
|
||||
WINDOWSEXPORT STRsensorinfo_C IS3Get_SensorInfo();
|
||||
WINDOWSEXPORT int IS3OptSnenser(int percent);
|
||||
WINDOWSEXPORT int IS3GetData(uint16_t *outdata,int shuttertime);
|
||||
WINDOWSEXPORT int IS3SetWeaveLenthCoeff(double *a,int lenth);
|
||||
WINDOWSEXPORT void IS3SetShutterOpen(int isopen);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //IS3LIB_IS3_INST_H
|
||||
382
myis11/src/IRIS_IS3/SensorIS3.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
#include"SensorIS3.h"
|
||||
|
||||
#include <Communication_Protocol.h>
|
||||
|
||||
#include "iostream"
|
||||
#include "IRIS_Method.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
static void split(const std::string& s, std::vector<std::string>& sv, char flag)
|
||||
{
|
||||
sv.clear();
|
||||
std::istringstream iss(s);
|
||||
std::string temp;
|
||||
|
||||
while (getline(iss, temp, flag)) {
|
||||
sv.push_back(temp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool SensorIS3::initSensor(int id)
|
||||
{
|
||||
|
||||
DataRetrun=GetDataBufferPTR();
|
||||
// IS1Sensor.SetPortName(id);
|
||||
SensorInfo=GetSensorInfo();
|
||||
// pinMode(22,OUTPUT);
|
||||
// pinMode(23,OUTPUT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
STRSensorInfo SensorIS3::GetSensorInfo()
|
||||
{
|
||||
|
||||
STRSensorInfo setem;
|
||||
if (!isSensorInit())
|
||||
{
|
||||
|
||||
return setem;
|
||||
}
|
||||
|
||||
|
||||
int retlenth= SendGetSensorInfo(GET_BASIC_INFO,sizeof(GET_BASIC_INFO));
|
||||
|
||||
char * result=new char[100];
|
||||
memcpy(result,DataRetrun,retlenth);
|
||||
result[retlenth]='\0';
|
||||
std::cout<<result<<std::endl;
|
||||
std::string str11(result);
|
||||
std::vector<std::string> strvec;
|
||||
split(str11,strvec,'-');
|
||||
setem.SensorName=strvec[0];
|
||||
|
||||
if (strvec.size()>=2) {
|
||||
setem.serialnumber=strvec[1];
|
||||
}
|
||||
delete[] result;
|
||||
|
||||
retlenth= SendGetSensorInfo(GET_BANDNUMBER,sizeof(GET_BASIC_INFO));
|
||||
int bandnumber=0;
|
||||
memcpy(&bandnumber,DataRetrun,retlenth);
|
||||
CoverLittleandBigbyNumber(&bandnumber,4);
|
||||
setem.BandNum=bandnumber;
|
||||
|
||||
setem.maxValue=65535;
|
||||
|
||||
setem.wavelenthlist=new float[setem.BandNum]();
|
||||
retlenth= SendGetSensorInfo(GET_WEAVE_COEFF,sizeof(GET_WEAVE_COEFF));
|
||||
double a[4];
|
||||
char tempaa[100];
|
||||
memcpy(tempaa,DataRetrun,100);
|
||||
int lenthtemp=sizeof(double);
|
||||
memcpy(a,DataRetrun,4*sizeof(double));
|
||||
|
||||
CoverLittleandBigbyNumber(a,sizeof(double));
|
||||
CoverLittleandBigbyNumber(a+1,sizeof(double));
|
||||
CoverLittleandBigbyNumber(a+2,sizeof(double));
|
||||
CoverLittleandBigbyNumber(a+3,sizeof(double));
|
||||
// a[0]=0;
|
||||
// a[1]=0;
|
||||
// a[2]=1;
|
||||
// a[3]=350;
|
||||
|
||||
|
||||
|
||||
// CoverLittleAndBig((char *)a,4*sizeof(float));
|
||||
int bandsss= setem.BandNum;
|
||||
#ifdef ARDUINO
|
||||
|
||||
Serial.print("a0:");
|
||||
Serial.print(a[0]);
|
||||
Serial.print(" a1:");
|
||||
Serial.print(a[1]);
|
||||
Serial.print(" a2:");
|
||||
Serial.print(a[2]);
|
||||
Serial.print(" a3:");
|
||||
Serial.println(a[3]);
|
||||
#endif
|
||||
|
||||
std::cout<<"a0:"<<a[0]<<" a1:"<<a[1]<<" a2:"<<a[2]<<" a3:"<<a[3]<<std::endl;
|
||||
|
||||
setem.a1=a[0];
|
||||
setem.a2=a[1];
|
||||
setem.a3=a[2];
|
||||
setem.a4=a[3];
|
||||
for ( int i = 1; i <=bandsss ; i++)
|
||||
{
|
||||
setem.wavelenthlist[i-1] = a[0] * i*i*i + a[1] * i*i + a[2] * i + a[3];
|
||||
setem.WavelenthStr=setem.WavelenthStr+std::to_string( setem.wavelenthlist[i-1])+",";
|
||||
}
|
||||
// delay(500);
|
||||
// Serial.write(dataretrun,retlenth);
|
||||
// memcpy(a,dataretrun+)
|
||||
u_char temp[2]={0x00,0x01};
|
||||
// retlenth=SendSettingCommand((u_char*)SET_AVERAGE_NUMBER,sizeof(SET_AVERAGE_NUMBER),temp,sizeof(temp));
|
||||
// Serial.println("init ok");
|
||||
|
||||
return setem;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SensorIS3::SetShutter(int id)
|
||||
{
|
||||
#ifdef ARDUINO
|
||||
switch (id) {
|
||||
case 0:
|
||||
{
|
||||
digitalWrite(22,LOW);
|
||||
digitalWrite(23,LOW);
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
case 1:{
|
||||
digitalWrite(23,HIGH);
|
||||
digitalWrite(22,LOW);
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
digitalWrite(22,HIGH);
|
||||
digitalWrite(23,LOW);
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
switch (id) {
|
||||
|
||||
case 0: {
|
||||
u_char a=1;
|
||||
SendSettingCommand(SET_SHUTTER_CLOSE,1, &a, 1);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
u_char a=1;
|
||||
//SendSettingCommand(SET_SHUTTER_CLOSE,1, &a, 1);
|
||||
SendSettingCommand(SET_SHUTTER_OPEN,1, &a, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void SensorIS3::SetWeaveLenthCoeff(double *a, int lenth) {
|
||||
u_char *datetosend=new u_char[lenth*sizeof(double)];
|
||||
printf("c++:a0:%f a1:%f a2:%f a3:%f\n",a[0],a[1],a[2],a[3]);
|
||||
CoverLittleandBigbyNumber(a,sizeof(double));
|
||||
CoverLittleandBigbyNumber(a+1,sizeof(double));
|
||||
CoverLittleandBigbyNumber(a+2,sizeof(double));
|
||||
CoverLittleandBigbyNumber(a+3,sizeof(double));
|
||||
|
||||
memcpy(datetosend,a,lenth*sizeof(double));
|
||||
SendSettingCommand(SET_WEAVE_COEFF,1,datetosend,lenth*sizeof(double));
|
||||
delete[] datetosend;
|
||||
// GetSensorInfo();
|
||||
}
|
||||
|
||||
void SensorIS3::GetOneDate(int msc)
|
||||
{
|
||||
|
||||
if (msc!=shutternow)
|
||||
{
|
||||
u_char shutter[4];
|
||||
memcpy(shutter,&msc,4);
|
||||
//交换下shutter 前后
|
||||
u_char shutterlitte[4];
|
||||
shutterlitte[0]=shutter[3];
|
||||
shutterlitte[1]=shutter[2];
|
||||
shutterlitte[2]=shutter[1];
|
||||
shutterlitte[3]=shutter[0];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int ret= SendSettingCommand(SET_INTEGRAL_TIME,1,shutterlitte,sizeof(shutterlitte));
|
||||
|
||||
|
||||
}
|
||||
shutternow=msc;
|
||||
size_t retsize= SendGetData(shutternow);
|
||||
|
||||
memcpy(DATABUFF,DataRetrun,515*2);
|
||||
//shortLittletoBiG(DATABUFF, SensorInfo.BandNum*2);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int SensorIS3::OptSnenser(int persent)
|
||||
{
|
||||
long minshuttertime=12;
|
||||
long maxtime = 10000;
|
||||
int maxvalue=SensorInfo.maxValue*1.0*persent / 100;
|
||||
int maxvaluenow = 0;
|
||||
float shutternow = 20;
|
||||
GetOneDate(shutternow);
|
||||
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
|
||||
|
||||
int numberoftry = 0;
|
||||
while (maxvaluenow<maxvalue*0.95 || maxvaluenow>maxvalue) {
|
||||
|
||||
if (maxvaluenow > maxvalue)
|
||||
{
|
||||
shutternow = shutternow *0.7;
|
||||
}
|
||||
else if (maxvaluenow==0)
|
||||
{
|
||||
shutternow =shutternow*10;
|
||||
}
|
||||
else
|
||||
{
|
||||
shutternow = maxvalue * 0.98 / (maxvaluenow * 1.0)*shutternow + 1;
|
||||
}
|
||||
if (shutternow > maxtime)
|
||||
{
|
||||
shutternow = maxtime;
|
||||
break;
|
||||
}
|
||||
if (shutternow < minshuttertime)
|
||||
{
|
||||
shutternow = minshuttertime;
|
||||
break;
|
||||
}
|
||||
GetOneDate(shutternow);
|
||||
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
|
||||
#ifdef ARDUINO
|
||||
Serial.print("now Shutter is :");
|
||||
Serial.print(shutternow);
|
||||
Serial.print(" maxvalue is :");
|
||||
Serial.println(maxvaluenow);
|
||||
#else
|
||||
std::cout<<"now Shutter is :"<<shutternow<<" maxvalue is :"<<maxvaluenow<<std::endl;
|
||||
#endif
|
||||
numberoftry++;
|
||||
if (numberoftry > 200)
|
||||
{
|
||||
|
||||
return maxtime;
|
||||
|
||||
}
|
||||
if (shutternow == maxtime)
|
||||
{
|
||||
|
||||
return maxtime;
|
||||
}
|
||||
}
|
||||
#ifdef ARDUINO
|
||||
Serial.print("zi dong value:");
|
||||
Serial.println(shutternow);
|
||||
#endif
|
||||
if (shutternow<0)
|
||||
{
|
||||
shutternow=maxtime;
|
||||
/* code */
|
||||
}
|
||||
|
||||
return shutternow;
|
||||
}
|
||||
|
||||
void SensorIS3::shortLittletoBiG(unsigned short *data,int lenth)
|
||||
{
|
||||
CoverLittleAndBig((char *)data,lenth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int SensorIS3::Getmaxvalue(unsigned short *data,int lenth)
|
||||
{
|
||||
int ret=-1;
|
||||
for (int i = 0; i < lenth; ++i) {
|
||||
if (data[i]>ret){
|
||||
ret=data[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SensorIS3::TakeOneJob()
|
||||
{
|
||||
|
||||
SetShutter(1);
|
||||
int shutter=OptSnenser(90);
|
||||
|
||||
shutterup=shutter;
|
||||
GetOneDate(shutter);
|
||||
// Serial.println("Finish Up ------Green2313123");
|
||||
if (UpData==nullptr)
|
||||
{
|
||||
UpData=new unsigned short[SensorInfo.BandNum*2];
|
||||
/* code */
|
||||
}
|
||||
|
||||
memcpy(UpData,DATABUFF,SensorInfo.BandNum*2);
|
||||
SetShutter(0);
|
||||
GetOneDate(shutter);
|
||||
for (int i = 0; i < SensorInfo.BandNum; ++i) {
|
||||
// UpData[i]=UpData[i]-DATABUFF[i];
|
||||
}
|
||||
shutterup=shutter;
|
||||
|
||||
bool dingbing=false;
|
||||
#ifdef DINBIAO
|
||||
String strout="1 shutteruo is "+String(shutterup)+" Finish Up ------Green change the fiber";
|
||||
PrintFunc(strout );
|
||||
digitalWrite(21, LOW);
|
||||
delay(60000);
|
||||
SensorInfo.SensorName=SensorInfo.SensorName+"cali";
|
||||
Serial.println("begindown");
|
||||
digitalWrite(21, HIGH);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
SetShutter(2);
|
||||
shutter=OptSnenser(90);
|
||||
shutterdown=shutter;
|
||||
GetOneDate(shutter);
|
||||
if (DownData==nullptr)
|
||||
{
|
||||
DownData=new unsigned short[SensorInfo.BandNum*2];
|
||||
/* code */
|
||||
}
|
||||
memcpy(DownData,DATABUFF,SensorInfo.BandNum*2);
|
||||
SetShutter(0);
|
||||
GetOneDate(shutter);
|
||||
|
||||
|
||||
for (int i = 0; i < SensorInfo.BandNum; ++i) {
|
||||
// DownData[i]=DownData[i]-DATABUFF[i];
|
||||
}
|
||||
shutterdown=shutter;
|
||||
|
||||
#ifdef DINBIAO
|
||||
String strout1="2 shutterdown is "+String(shutterdown)+" Down Finish ------Blue";
|
||||
PrintFunc(strout1 );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
SensorIS3::SensorIS3()
|
||||
{
|
||||
shutternow=0;
|
||||
// DataRetrun=GetDataBufferPTR();
|
||||
}
|
||||
44
myis11/src/IRIS_IS3/SensorIS3.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef SENSORIS3_H
|
||||
#define SENSORIS3_H
|
||||
|
||||
#include "comon.h"
|
||||
#include "IS3Comon.h"
|
||||
|
||||
|
||||
|
||||
class SensorIS3 {
|
||||
public:
|
||||
SensorIS3();
|
||||
STRSensorInfo SensorInfo;
|
||||
bool initSensor(int id = 2);
|
||||
STRSensorInfo GetSensorInfo();
|
||||
void SetShutter(int id);// 0 dark 1 green 2 blue
|
||||
void SetWeaveLenthCoeff(double *a,int lenth);
|
||||
void GetOneDate(int msc);
|
||||
int OptSnenser(int percent);
|
||||
unsigned short DATABUFF[2048];
|
||||
int shutterup,shutterdown;
|
||||
unsigned short *DownData=nullptr;
|
||||
unsigned short *UpData=nullptr;
|
||||
void shortLittletoBiG( unsigned short *data,int lenth);
|
||||
|
||||
int Getmaxvalue(unsigned short *data,int lenth);
|
||||
void TakeOneJob();
|
||||
PRINTFUNC PrintFunc;
|
||||
|
||||
|
||||
|
||||
int shutternow;
|
||||
//uint16_t result[2048];
|
||||
|
||||
|
||||
u_char *DataRetrun;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,7 +1,8 @@
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
typedef unsigned char u_char;
|
||||
/**
|
||||
* @brief 串口写函数类型
|
||||
@ -1,16 +1,21 @@
|
||||
#include "IS11Comon.h"
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#endif
|
||||
|
||||
void delay(int ms){
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
#else
|
||||
#include <unistd.h> // For usleep
|
||||
|
||||
void delay(int ms){
|
||||
usleep(ms * 1000); // Convert milliseconds to microseconds
|
||||
}
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
u_char BufferForRead[10000];
|
||||
int TotalIndexNow = 0;
|
||||
@ -18,7 +23,7 @@ u_char BufferFortempWrite[1000];
|
||||
// MySerialWrite=nullptr;
|
||||
SERIALWRITE MySerialWrite = nullptr;
|
||||
SERIALREAD MySerialRead = nullptr;
|
||||
bool ISIS11Init = false;
|
||||
bool isIS3Init = false;
|
||||
uint16_t crc16(const uint8_t *data, size_t len, uint16_t polynomial)
|
||||
{
|
||||
uint16_t i, j, tmp, CRC16;
|
||||
@ -211,7 +216,7 @@ void InitFunction(SERIALWRITE a, SERIALWRITE readfunc)
|
||||
MySerialRead = readfunc;
|
||||
//std::string temp = "01";
|
||||
//a((u_char *)temp.c_str(), 2);
|
||||
ISIS11Init = true;
|
||||
isIS3Init = true;
|
||||
}
|
||||
|
||||
u_char *GetDataBufferPTR()
|
||||
@ -220,7 +225,7 @@ u_char *GetDataBufferPTR()
|
||||
}
|
||||
bool isSensorInit()
|
||||
{
|
||||
return ISIS11Init;
|
||||
return isIS3Init;
|
||||
}
|
||||
|
||||
void CoverLittleAndBig(char *data, int lenth)
|
||||
|
||||
@ -12,13 +12,14 @@
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#ifdef __cplusplus
|
||||
#include "comon.h"
|
||||
extern "C" {
|
||||
#endif
|
||||
#define COMMAND_GET 0x03
|
||||
#define COMMAND_SET 0x06
|
||||
#define COMMAND_MULTSET 0x10
|
||||
#define POLYNOMIAL 0xa001 //modbus crc
|
||||
#include "comon.h"
|
||||
|
||||
|
||||
|
||||
const u_char GET_ADDRESS[]={0x01,0x03,0x00,0x01,0x00,0x01};
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#include "IS11_INST.h"
|
||||
#include "iostream"
|
||||
#include "cstring"
|
||||
|
||||
#include <cstdio> // 对于 snprintf
|
||||
SensorIS11 *thissensorIS11;
|
||||
int IS11SensorInit()
|
||||
{
|
||||
@ -34,10 +34,12 @@ STRsensorinfo_C Get_SensorInfo() {
|
||||
STRSensorInfo sensorinfo= thissensorIS11->SensorInfo;
|
||||
STRsensorinfo_C sensorinfo_c;
|
||||
//把sensorname 拷贝到sensorinfo_c
|
||||
strcpy_s(sensorinfo_c.SensorName,sensorinfo.SensorName.c_str());
|
||||
//strcpy_s(sensorinfo_c.SensorName,sensorinfo.SensorName.c_str());
|
||||
snprintf(sensorinfo_c.SensorName, sizeof(sensorinfo_c.SensorName), "%s", sensorinfo.SensorName.c_str());
|
||||
sensorinfo_c.BandNum = sensorinfo.BandNum;
|
||||
sensorinfo_c.maxValue = sensorinfo.maxValue;
|
||||
strcpy_s(sensorinfo_c.serialnumber,sensorinfo.serialnumber.c_str());
|
||||
//strcpy_s(sensorinfo_c.serialnumber,sensorinfo.serialnumber.c_str());
|
||||
snprintf(sensorinfo_c.serialnumber, sizeof(sensorinfo_c.serialnumber), "%s", sensorinfo.serialnumber.c_str());
|
||||
sensorinfo_c.a1 = sensorinfo.a1;
|
||||
sensorinfo_c.a2 = sensorinfo.a2;
|
||||
sensorinfo_c.a3 = sensorinfo.a3;
|
||||
|
||||
@ -19,12 +19,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WINDOWSEXPORT __declspec(dllexport) // Windows下导出函数
|
||||
#else
|
||||
#define WINDOWSEXPORT // Linux下导出函数
|
||||
#endif
|
||||
|
||||
__declspec(dllexport) int IS11SensorInit();
|
||||
__declspec(dllexport) void Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc);
|
||||
__declspec(dllexport) STRsensorinfo_C Get_SensorInfo();
|
||||
__declspec(dllexport) int IS11OptSnenser(int percent);
|
||||
__declspec(dllexport) int IS11GetData(uint16_t *outdata,int shuttertime);
|
||||
WINDOWSEXPORT int IS11SensorInit();
|
||||
WINDOWSEXPORT void Set_Serial_FUN(SERIALWRITE writefunc,SERIALWRITE readfunc);
|
||||
WINDOWSEXPORT STRsensorinfo_C Get_SensorInfo();
|
||||
WINDOWSEXPORT int IS11OptSnenser(int percent);
|
||||
WINDOWSEXPORT int IS11GetData(uint16_t *outdata,int shuttertime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -1,5 +1,14 @@
|
||||
#include"SensorIS11.h"
|
||||
#include "iostream"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
bool SensorIS11::initSensor(int id)
|
||||
{
|
||||
|
||||
|
||||
@ -14,10 +14,10 @@
|
||||
|
||||
#include "test.h"
|
||||
#include "stdio.h"
|
||||
void test() {
|
||||
printf("hello world sdfsdf12131321321313132\n");
|
||||
printf("dsdf\n");
|
||||
}
|
||||
//void test() {
|
||||
// printf("hello world sdfsdf12131321321313132\n");
|
||||
// printf("dsdf\n");
|
||||
//}
|
||||
|
||||
//int isSensorInit() {
|
||||
//
|
||||
|
||||
@ -17,13 +17,13 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cinttypes>
|
||||
|
||||
extern "C" __declspec(dllexport) std::int32_t abs1(std::int32_t n) {
|
||||
return 100;
|
||||
}
|
||||
extern "C" {
|
||||
|
||||
}
|
||||
extern "C" __declspec(dllexport) void test();
|
||||
//
|
||||
//extern "C" __declspec(dllexport) std::int32_t abs1(std::int32_t n) {
|
||||
// return 100;
|
||||
//}
|
||||
//extern "C" {
|
||||
//
|
||||
//}
|
||||
//extern "C" __declspec(dllexport) void test();
|
||||
|
||||
#endif //MYIS11_TEST_H
|
||||
|
||||
1
myis11/src/thirdpart/iris_proto_tool
Submodule
1868
package-lock.json
generated
@ -21,19 +21,23 @@
|
||||
"element-plus": "^2.4.4",
|
||||
"json-editor-vue3": "^1.1.1",
|
||||
"less": "^4.2.0",
|
||||
"maptalks": "^1.1.3",
|
||||
"markdown-it": "^14.1.0",
|
||||
"mitt": "^3.0.1",
|
||||
"ol": "^10.6.1",
|
||||
"serialport": "^12.0.0",
|
||||
"vue": "^3.3.4",
|
||||
"vue-drag-resize": "^2.0.3",
|
||||
"vue-json-viewer": "^3.0.4",
|
||||
"vue-markdown-render": "^2.2.1",
|
||||
"vue3-json-editor": "^1.1.5",
|
||||
"vue3-konami-code": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arco-design/web-vue": "^2.55.2",
|
||||
"@arco-design/web-vue": "^2.57.0",
|
||||
"@tauri-apps/cli": "^1.5.11",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"unplugin-vue-components": "^0.27.0",
|
||||
"vite": "^5.0.0"
|
||||
"vite": "^6.2.3"
|
||||
}
|
||||
}
|
||||
|
||||
85
src-tauri/Cargo.lock
generated
@ -491,7 +491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -522,7 +522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -570,7 +570,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.11.1",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -592,7 +592,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
||||
dependencies = [
|
||||
"darling_core 0.20.9",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -860,7 +860,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1691,6 +1691,7 @@ dependencies = [
|
||||
"find_peaks",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"nalgebra 0.33.2",
|
||||
"ndarray",
|
||||
"ndarray-ndimage",
|
||||
"ndarray-stats",
|
||||
@ -1730,7 +1731,7 @@ checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"matrixmultiply",
|
||||
"nalgebra-macros 0.2.1",
|
||||
"nalgebra-macros 0.2.2",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
@ -1738,6 +1739,22 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.33.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"matrixmultiply",
|
||||
"nalgebra-macros 0.2.2",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"simba 0.9.0",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra-macros"
|
||||
version = "0.1.0"
|
||||
@ -1751,13 +1768,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra-macros"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998"
|
||||
checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1870,6 +1887,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
@ -1900,6 +1927,7 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
@ -2184,7 +2212,7 @@ dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2328,9 +2356,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -2670,7 +2698,7 @@ checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2693,7 +2721,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2754,7 +2782,7 @@ dependencies = [
|
||||
"darling 0.20.9",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2863,6 +2891,19 @@ dependencies = [
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"paste",
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
@ -3000,9 +3041,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.64"
|
||||
version = "2.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3345,7 +3386,7 @@ checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3446,7 +3487,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3536,7 +3577,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3734,7 +3775,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -3768,7 +3809,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
"syn 2.0.100",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -28,6 +28,8 @@ csv = "1.3.0"
|
||||
tklog = "0.0.8"
|
||||
libc = "0.2.156"
|
||||
chrono = "0.4.38"
|
||||
nalgebra = "0.33.2"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
[Setup]
|
||||
AppName=MyApp
|
||||
AppVersion=1.0
|
||||
DefaultDirName={pf}\MyApp
|
||||
OutputDir=.
|
||||
OutputBaseFilename=MyAppInstaller
|
||||
|
||||
[Files]
|
||||
Source: "src-tauri/target/release/bundle/msi/*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\path\to\vsruntime\installer.exe"; Parameters: "/quiet /norestart"; Flags: waituntilterminated
|
||||
@ -1,3 +1,13 @@
|
||||
fn main() {
|
||||
// 根据目标操作系统设置不同的链接搜索路径
|
||||
if cfg!(target_os = "linux") {
|
||||
println!("cargo:rustc-link-search=native=../myis11/project/is3/cmake-build-release-visual-studio");
|
||||
println!("cargo:rustc-link-search=native=../myis11/project/is11/cmake-build-release-visual-studio");
|
||||
// 注意:在 Linux 上,通常不需要显式地告诉 cargo 链接 .so 文件,
|
||||
// 只要 #[link(name = "...", kind = "dylib")] 存在,并且库在搜索路径中,
|
||||
// 链接器就会找到它们。但如果你想明确,也可以添加:
|
||||
// println!("cargo:rustc-link-lib=dylib=iris_is3lib");
|
||||
// println!("cargo:rustc-link-lib=dylib=is11lib");
|
||||
}
|
||||
tauri_build::build()
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
{"pathofsave":"D:\\06Learn\\rust\\tarui","Filename":"testaa","caijiavgNumber":"1","useSG":false,"usehighpass":false,"Dispatcher":{"isenable":true,"begin":"14:25","end":"23:59"}}
|
||||
{"pathofsave":null,"Filename":"testaa","caijiavgNumber":"1","useSG":false,"usehighpass":false,"Dispatcher":{"isenable":true,"begin":"09:28","end":"23:59"},"sensor_typeforset":"IS3"}
|
||||
BIN
src-tauri/data46.iris
Normal file
2
src-tauri/debug_pre-build.ps1
Normal file
@ -0,0 +1,2 @@
|
||||
copy .\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022\\is11lib.dll ./src-tauri
|
||||
copy .\\myis11\\project\\is3\\cmake-build-debug-visual-studio\\iris_is3lib.dll ./src-tauri
|
||||
BIN
src-tauri/icons/icon.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
src-tauri/iris_data_example.iris
Normal file
BIN
src-tauri/iris_is3lib.dll
Normal file
BIN
src-tauri/msvcp140.dll
Normal file
@ -1,2 +1,2 @@
|
||||
copy ..\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022\\is11lib.dll ./src-tauri
|
||||
|
||||
copy myis11\\project\\is3\\cmake-build-release-visual-studio\\iris_is3lib.dll ./src-tauri
|
||||
|
||||
@ -26,3 +26,18 @@ pub fn gaussian_filter_high(data: Vec<f64>, sigma: f64) -> Vec<f64> {
|
||||
pub fn find_peek(data: Vec<f64>, minheigh: f64) -> Vec<(u32, f64)> {
|
||||
spectraltools::find_peek(data, minheigh)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn compute_weave_coeff(x: Vec<f64>, y: Vec<f64>) -> Vec<f64> {
|
||||
spectraltools::compute_weave_coeff(x, y)
|
||||
}
|
||||
|
||||
|
||||
pub fn polynomial_smooth_u32(y: &[u32], degree: usize) -> Vec<u32> {
|
||||
smoothmethod::polynomial_smooth_u32(y, degree)
|
||||
}
|
||||
|
||||
pub fn polynomial_smooth_u16(y: Vec<u16>, degree: usize) -> Vec<u16> {
|
||||
|
||||
smoothmethod::polynomial_smooth_u16(&y, degree)
|
||||
}
|
||||
@ -6,7 +6,7 @@ use ndarray_ndimage::{gaussian_filter, BorderMode};
|
||||
|
||||
pub fn high_pass_gaussian_filter(input: Vec<f64>, sigma: f64) -> Vec<f64> {
|
||||
// 将输入 Vec<f64> 转换为 Array1<f64>
|
||||
let mut input_array = Array1::from_vec(input);
|
||||
let input_array = Array1::from_vec(input);
|
||||
// for i in 0..input_array.len(){
|
||||
//
|
||||
// input_array[i]=input_array[i]*input_array[i]/( 65535f64);
|
||||
@ -16,7 +16,7 @@ pub fn high_pass_gaussian_filter(input: Vec<f64>, sigma: f64) -> Vec<f64> {
|
||||
|
||||
|
||||
// 高斯低通滤波
|
||||
let mut low_pass = gaussian_filter(&input_array, sigma, 0, BorderMode::Reflect, 3);
|
||||
let low_pass = gaussian_filter(&input_array, sigma, 0, BorderMode::Reflect, 3);
|
||||
// Modify the result: set values less than zero to zero
|
||||
println!("{:?}",low_pass);
|
||||
// 高通滤波:原始信号 - 低通滤波结果
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
extern crate savgol_rs;
|
||||
|
||||
use nalgebra::{DMatrix, DVector};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use savgol_rs::savgol_filter;
|
||||
pub fn savgol(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
|
||||
@ -8,7 +9,134 @@ pub fn savgol(data: Vec<f64>, window: usize, order: usize) -> Vec<f64> {
|
||||
savgol_filter(&svinput).unwrap()
|
||||
}
|
||||
|
||||
/// 多项式拟合函数 (f64版本)
|
||||
///
|
||||
/// 参数:
|
||||
/// - x: x坐标序列
|
||||
/// - y: y坐标序列
|
||||
/// - degree: 多项式次数 (7或8)
|
||||
///
|
||||
/// 返回: 平滑后的y值序列
|
||||
pub fn polynomial_fit_f64(x: &[f64], y: &[f64], degree: usize) -> Vec<f64> {
|
||||
assert_eq!(x.len(), y.len(), "x和y的长度必须相同");
|
||||
if x.len() < degree + 1 {
|
||||
panic!("数据点数量必须大于多项式次数");
|
||||
}
|
||||
let n = x.len();
|
||||
let y_vec = DVector::from_vec(y.to_vec());
|
||||
// 构建范德蒙矩阵
|
||||
let mut vandermonde = DMatrix::zeros(n, degree + 1);
|
||||
for i in 0..n {
|
||||
for j in 0..=degree {
|
||||
vandermonde[(i, j)] = x[i].powi(j as i32);
|
||||
}
|
||||
}
|
||||
// 解最小二乘问题 - 新版本nalgebra的调用方式
|
||||
let svd = vandermonde.svd(true, true);
|
||||
let coefficients = svd.solve(&y_vec, f64::EPSILON).unwrap();
|
||||
// 计算拟合值
|
||||
let fitted_y: Vec<f64> = x
|
||||
.iter()
|
||||
.map(|&xi| {
|
||||
(0..=degree).fold(0.0, |acc, j| acc + coefficients[j] * xi.powi(j as i32))
|
||||
})
|
||||
.collect();
|
||||
fitted_y
|
||||
}
|
||||
/// 多项式拟合函数 (u32版本)
|
||||
///
|
||||
/// 参数:
|
||||
/// - x: x坐标序列
|
||||
/// - y: y坐标序列
|
||||
/// - degree: 多项式次数 (7或8)
|
||||
///
|
||||
/// 返回: 平滑后的y值序列
|
||||
pub fn polynomial_fit_u32(x: &[u32], y: &[u32], degree: usize) -> Vec<u32> {
|
||||
// 转换为f64处理
|
||||
let x_f64: Vec<f64> = x.iter().map(|&xi| xi as f64).collect();
|
||||
let y_f64: Vec<f64> = y.iter().map(|&yi| yi as f64).collect();
|
||||
|
||||
let fitted_f64 = polynomial_fit_f64(&x_f64, &y_f64, degree);
|
||||
|
||||
// 转换回u32,处理可能的负值(截断为0)和溢出
|
||||
fitted_f64
|
||||
.into_iter()
|
||||
.map(|y| {
|
||||
if y < 0.0 {
|
||||
0
|
||||
} else {
|
||||
u32::try_from(y.round() as i64).unwrap_or(u32::MAX)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
/// 简化版:当x是等间距时的平滑函数 (u32版本)
|
||||
pub fn polynomial_smooth_u32(y: &[u32], degree: usize) -> Vec<u32> {
|
||||
let x: Vec<u32> = (0..y.len() as u32).collect();
|
||||
polynomial_fit_u32(&x, y, degree)
|
||||
}
|
||||
/// 多项式拟合函数 (u16版本)
|
||||
pub fn polynomial_fit_u16(x: &[u16], y: &[u16], degree: usize) -> Vec<u16> {
|
||||
let x_f64: Vec<f64> = x.iter().map(|&xi| xi as f64).collect();
|
||||
let y_f64: Vec<f64> = y.iter().map(|&yi| yi as f64).collect();
|
||||
|
||||
let fitted_f64 = polynomial_fit_f64(&x_f64, &y_f64, degree);
|
||||
|
||||
fitted_f64
|
||||
.into_iter()
|
||||
.map(|y| {
|
||||
if y < 0.0 {
|
||||
0
|
||||
} else if y > u16::MAX as f64 {
|
||||
u16::MAX
|
||||
} else {
|
||||
y.round() as u16
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
/// 简化版:当x是等间距时的平滑函数 (u16版本)
|
||||
pub fn polynomial_smooth_u16(y: &[u16], degree: usize) -> Vec<u16> {
|
||||
let x: Vec<u16> = (0..y.len() as u16).collect();
|
||||
polynomial_fit_u16(&x, y, degree)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_polynomial_fit() {
|
||||
// 测试数据: 一个简单的二次函数加一些噪声
|
||||
let x = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
|
||||
let y = vec![1.0, 3.0, 6.0, 10.0, 15.0, 24.0, 35.0, 50.0, 65.0, 82.0];
|
||||
|
||||
// 2次多项式拟合应该能很好拟合
|
||||
let fitted = polynomial_fit_f64(&x, &y, 2);
|
||||
assert_eq!(fitted.len(), y.len());
|
||||
|
||||
// 检查拟合结果是否接近原始数据
|
||||
for (original, fitted) in y.iter().zip(fitted.iter()) {
|
||||
assert!((original - fitted).abs() < 5.0);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_polynomial_smooth() {
|
||||
// 测试数据: 一个简单的上升序列加一些噪声
|
||||
let y = vec![
|
||||
10,12,11,13,12,14,13,15,14,16,
|
||||
15,17,16,18,17,19,18,20,19,21,
|
||||
];
|
||||
|
||||
// 7次多项式平滑
|
||||
let smoothed_7 = polynomial_smooth_u32(&y, 7);
|
||||
print!("smoothed_7: {:?}", smoothed_7);
|
||||
assert_eq!(smoothed_7.len(), y.len());
|
||||
|
||||
// 8次多项式平滑
|
||||
let smoothed_8 = polynomial_smooth_u32(&y, 8);
|
||||
assert_eq!(smoothed_8.len(), y.len());
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_savgol() {
|
||||
// 示例数据
|
||||
|
||||
@ -39,7 +39,7 @@ pub fn interpolate_spline<T: Copy + Into<f64>,>(x_t: Vec<T>, y_t: Vec<T>, step:
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_t: Vec<T>, y_t: Vec<T>, x_target: Vec<f64>) -> Result<Vec<(f64)>, Box<dyn Error>> {
|
||||
pub fn interpolate_spline_at_points<T: Copy + Into<f64>>(x_t: Vec<T>, y_t: Vec<T>, x_target: Vec<f64>) -> Result<Vec<f64>, Box<dyn Error>> {
|
||||
let x: Vec<f64> = x_t.iter().map(|&x| x.into()).collect();
|
||||
let y: Vec<f64> = y_t.iter().map(|&y| y.into()).collect();
|
||||
|
||||
@ -128,7 +128,51 @@ fn read_csv_to_vec(file_path: &str) -> Result<Vec<f64>, Box<dyn Error>> {
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
use nalgebra::{DMatrix, DVector};
|
||||
|
||||
pub fn compute_weave_coeff(x_data:Vec<f64>,y_data:Vec<f64>)->Vec<f64>{
|
||||
|
||||
assert_eq!(x_data.len(), y_data.len());
|
||||
|
||||
let n = x_data.len();
|
||||
|
||||
// 构建设计矩阵 X 和观测向量 y
|
||||
let mut x_matrix = DMatrix::zeros(n, 4); // 三阶多项式有 4 个系数
|
||||
let y_vector = DVector::from_vec(y_data.clone());
|
||||
|
||||
for (i, &x) in x_data.iter().enumerate() {
|
||||
x_matrix[(i, 0)] = 1.0; // 常数项
|
||||
x_matrix[(i, 1)] = x; // x
|
||||
x_matrix[(i, 2)] = x.powi(2); // x²
|
||||
x_matrix[(i, 3)] = x.powi(3); // x³
|
||||
}
|
||||
|
||||
// 使用正规方程求解最小二乘问题: (XᵀX)β = Xᵀy
|
||||
let xt = x_matrix.transpose();
|
||||
let xtx = &xt * &x_matrix;
|
||||
let xty = &xt * &y_vector;
|
||||
|
||||
// 求解方程 (XᵀX)β = Xᵀy
|
||||
let beta = xtx
|
||||
.lu()
|
||||
.solve(&xty)
|
||||
.expect("无法求解正规方程,可能是矩阵奇异");
|
||||
|
||||
// 输出拟合系数
|
||||
println!("拟合的三阶多项式系数:");
|
||||
println!("y = {:.4} + {:.4}x + {:.4}x² + {:.4}x³", beta[0], beta[1], beta[2], beta[3]);
|
||||
|
||||
// 示例:使用拟合的多项式进行预测
|
||||
let x_test = 6.0;
|
||||
let y_pred = beta[0] + beta[1]*x_test + beta[2]*x_test.powi(2) + beta[3]*x_test.powi(3);
|
||||
println!("对于 x = {:.2}, 预测的 y = {:.4}", x_test, y_pred);
|
||||
let mut retvec=Vec::new();
|
||||
for i in 0..4{
|
||||
retvec.push(beta[i]);
|
||||
}
|
||||
retvec
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_peek(){
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
|
||||
use super::serport::serport::*;
|
||||
use super::mylog::*;
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
360
src-tauri/src/iris_spectral/mod.rs
Normal file
@ -0,0 +1,360 @@
|
||||
use super::mydefine::*;
|
||||
pub mod spectralserver;
|
||||
pub mod spectralbase;
|
||||
use std::fs;
|
||||
use super::mylog::*;
|
||||
use serde_json::json;
|
||||
use spectralserver::calibrate_file;
|
||||
use std::ffi::CStr;
|
||||
use std::path::Path;
|
||||
pub fn delete_file(filepath: String) -> String {
|
||||
let file_path = Path::new(&filepath);
|
||||
if file_path.exists() {
|
||||
fs::remove_file(file_path).unwrap();
|
||||
"OK".to_string()
|
||||
} else {
|
||||
"文件不存在".to_string()
|
||||
}
|
||||
}
|
||||
pub fn sendtoport_andgetreturn(
|
||||
data: serde_json::Value,
|
||||
datatype: serde_json::Value,
|
||||
) -> Result<RetStruct, String> {
|
||||
let command = data.get("command").unwrap().to_string();
|
||||
//println!("start_collect data:{}", data.to_string());
|
||||
match command.as_str() {
|
||||
|
||||
"\"start_collect_flat\"" => {
|
||||
return start_collect_flat(data, datatype);
|
||||
},
|
||||
|
||||
"\"start_collect_dark\"" => {
|
||||
return start_collect_dark(data, datatype);
|
||||
},
|
||||
"\"get_sensor_info\"" => {
|
||||
spectralserver::is11_init();
|
||||
logtorust("init sensor ok".to_string());
|
||||
let sensor_info = spectralserver::is11_get_sensor_info();
|
||||
let shuttertime = spectralserver::get_shuttertime();
|
||||
let sensor_name_cstr = unsafe { CStr::from_ptr(sensor_info.SensorName.as_ptr()) };
|
||||
let sensor_name = sensor_name_cstr.to_str().unwrap();
|
||||
let serilnumber_cstr = unsafe { CStr::from_ptr(sensor_info.serialnumber.as_ptr()) };
|
||||
let serilnumber = serilnumber_cstr.to_str().unwrap();
|
||||
//定义一个json对象
|
||||
let jsonforret = json!({
|
||||
"bochangxishu":{
|
||||
"a0":sensor_info.a1,
|
||||
"a1":sensor_info.a2,
|
||||
"a2":sensor_info.a3,
|
||||
"a3":sensor_info.a4,
|
||||
},
|
||||
"serialnumber":serilnumber,
|
||||
"bandnum":sensor_info.BandNum,
|
||||
"bandsum":sensor_info.BandNum,
|
||||
|
||||
"name":sensor_name,
|
||||
// "name":sensor_name,
|
||||
"version":"1.0.0",
|
||||
"return_data_type":0,
|
||||
"work_mode":"advanced_mode",
|
||||
"sensor_type":"IRIS-Sensor",
|
||||
"fiber_type":"Single",
|
||||
"shutter_time":shuttertime,
|
||||
"has_shutter":true,
|
||||
|
||||
|
||||
});
|
||||
let califiename=format!("calibratefile/{}_{}_upgain.bin",sensor_name,serilnumber);
|
||||
spectralserver::load_all_calibrate_file(califiename);
|
||||
logtorust(format!("get_sensor_info:{}", jsonforret.to_string()));
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonforret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
}
|
||||
"\"start_opt\"" => {
|
||||
spectralserver::opt_sensor(90);
|
||||
let jsonforret = json!({
|
||||
"command":"start_opt"
|
||||
|
||||
});
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonforret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
}
|
||||
"\"get_opt\"" => {
|
||||
println!("get_opt");
|
||||
let ret = get_opt_result();
|
||||
return ret;
|
||||
}
|
||||
"\"start_collect\"" => {
|
||||
return start_collect(data, datatype);
|
||||
}
|
||||
|
||||
"\"get_caiji_state\"" => {
|
||||
let (caiji_state, caiji_state_str,percent) = spectralserver::get_now_stat();
|
||||
let jsonforret = json!({
|
||||
"caiji_state":caiji_state,
|
||||
"info":caiji_state_str,
|
||||
"percent":percent,
|
||||
"return_data_type":0,
|
||||
});
|
||||
//logtorust(format!("get_caiji_state:{}", jsonforret.to_string()));
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonforret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
}
|
||||
"\"get_data\"" => {
|
||||
return get_data(data, datatype);
|
||||
},
|
||||
"\"get_data_flat\"" => {
|
||||
return get_data_flat(data, datatype);
|
||||
},
|
||||
"\"get_data_dark\"" => {
|
||||
return get_data_dark(data, datatype);
|
||||
},
|
||||
"\"set_shutter_time\"" => {
|
||||
return set_shutter_time(data, datatype);
|
||||
},
|
||||
_ => {
|
||||
return Err("command not found ".to_string() + "command is:" + &command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn get_opt_result() -> Result<RetStruct, String> {
|
||||
let shuttertime = spectralserver::get_shuttertime();
|
||||
|
||||
let jsonret = json!({
|
||||
"opt":shuttertime,
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
}
|
||||
pub fn set_shutter_time(data: serde_json::Value,
|
||||
datatype: serde_json::Value) -> Result<RetStruct, String> {
|
||||
|
||||
|
||||
let shuttertime: u32;
|
||||
if data.get("shutter_time").is_none() {
|
||||
shuttertime = spectralserver::get_shuttertime() as u32;
|
||||
} else {
|
||||
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
|
||||
spectralserver::set_shutter_time(shuttertime);
|
||||
}
|
||||
|
||||
|
||||
let jsonret = json!({
|
||||
"shuttertime":"ok",
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
}
|
||||
pub fn start_collect(
|
||||
data: serde_json::Value,
|
||||
datatype: serde_json::Value,
|
||||
) -> Result<RetStruct, String> {
|
||||
|
||||
|
||||
let shuttertime: u32;
|
||||
if data.get("shutter_time").is_none() {
|
||||
shuttertime =spectralserver::get_shuttertime() as u32;
|
||||
} else {
|
||||
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
|
||||
}
|
||||
//判断是否有这个参数
|
||||
|
||||
let removedark: bool;
|
||||
if data.get("remove_dark").is_none() {
|
||||
removedark = false;
|
||||
} else {
|
||||
if data.get("remove_dark").unwrap().is_boolean() {
|
||||
removedark = data.get("remove_dark").unwrap().as_bool().unwrap();
|
||||
} else if data.get("remove_dark").unwrap().is_string() {
|
||||
let remove_dark_str = data.get("remove_dark").unwrap().as_str().unwrap();
|
||||
if remove_dark_str == "yes" {
|
||||
removedark = true;
|
||||
} else {
|
||||
removedark = false;
|
||||
}
|
||||
} else {
|
||||
removedark = false;
|
||||
}
|
||||
}
|
||||
|
||||
let computeflat = spectralserver::get_is_computeref();
|
||||
logtorust(format!("start_collect,shutter time is:{}", shuttertime));
|
||||
if !data.get("collect_times").is_none() {
|
||||
if data.get("collect_times").unwrap().is_u64() {
|
||||
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
|
||||
spectralserver::set_average_number(collect_times,collect_times,collect_times );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
spectralserver::collect(shuttertime, removedark, computeflat);
|
||||
let jsonret = json!({
|
||||
"command":"start_collect"
|
||||
|
||||
});
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn start_collect_dark(
|
||||
data: serde_json::Value,
|
||||
datatype: serde_json::Value,
|
||||
) -> Result<RetStruct, String> {
|
||||
let shuttertime: u32;
|
||||
if data.get("shutter_time").is_none() {
|
||||
shuttertime = spectralserver::get_shuttertime() as u32;
|
||||
} else {
|
||||
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
|
||||
}
|
||||
//判断是否有这个参数
|
||||
if !data.get("collect_times").is_none() {
|
||||
if data.get("collect_times").unwrap().is_u64() {
|
||||
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
|
||||
spectralserver::set_average_number(collect_times,collect_times,collect_times );
|
||||
}
|
||||
}
|
||||
|
||||
spectralserver::collcect_dark(shuttertime);
|
||||
let jsonret = json!({
|
||||
"command":"start_collect_dark"
|
||||
|
||||
});
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn start_collect_flat(
|
||||
data: serde_json::Value,
|
||||
datatype: serde_json::Value,
|
||||
) -> Result<RetStruct, String> {
|
||||
let shuttertime: u32;
|
||||
if data.get("shutter_time").is_none() {
|
||||
shuttertime = spectralserver::get_shuttertime() as u32;
|
||||
} else {
|
||||
shuttertime = data.get("shutter_time").unwrap().as_u64().unwrap() as u32;
|
||||
}
|
||||
//判断是否有这个参数
|
||||
if !data.get("collect_times").is_none() {
|
||||
if data.get("collect_times").unwrap().is_u64() {
|
||||
let collect_times = data.get("collect_times").unwrap().as_u64().unwrap() as u32;
|
||||
spectralserver::set_average_number(collect_times,collect_times,collect_times );
|
||||
}
|
||||
}
|
||||
|
||||
spectralserver::collcect_flat(shuttertime);
|
||||
let jsonret = json!({
|
||||
"command":"start_collect_flat"
|
||||
|
||||
});
|
||||
return Ok(RetStruct {
|
||||
datatype: 0,
|
||||
content: jsonret.to_string(),
|
||||
data: IS11DataStruct::default(),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn get_data(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
|
||||
let mut is11_data = spectralserver::get_data();
|
||||
println!("get_data datatype:{}", data["return_data_type"]);
|
||||
let retrun_data_type = data["return_data_type"].as_u64().unwrap();
|
||||
if retrun_data_type ==0x12 || retrun_data_type ==0x13 {
|
||||
|
||||
is11_data=calibrate_file(&is11_data)
|
||||
}
|
||||
|
||||
let jsonret = json!({
|
||||
"command":"get_data"
|
||||
|
||||
});
|
||||
|
||||
return Ok(RetStruct {
|
||||
datatype: 2,
|
||||
content: jsonret.to_string(),
|
||||
data: is11_data,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn get_data_flat(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
|
||||
let is11_data = spectralserver::get_data_flat();
|
||||
|
||||
let jsonret = json!({
|
||||
"command":"get_data_flat"
|
||||
|
||||
});
|
||||
|
||||
return Ok(RetStruct {
|
||||
datatype: 2,
|
||||
content: jsonret.to_string(),
|
||||
data: is11_data,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn get_data_dark(data: serde_json::Value, datatype: serde_json::Value) -> Result<RetStruct, String> {
|
||||
let is11_data = spectralserver::get_data_dark();
|
||||
|
||||
let jsonret = json!({
|
||||
"command":"get_data_dark"
|
||||
|
||||
});
|
||||
|
||||
return Ok(RetStruct {
|
||||
datatype: 2,
|
||||
content: jsonret.to_string(),
|
||||
data: is11_data,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_weave_coeff(
|
||||
specnumber: i32,
|
||||
a0: f64,
|
||||
a1: f64,
|
||||
a2: f64,
|
||||
a3: f64,
|
||||
) -> String {
|
||||
println!("set_weave_coeff:specnumber:{},a0:{},a1:{},a2:{},a3:{}", specnumber, a0, a1, a2, a3);
|
||||
spectralserver::set_weave_coeff(specnumber, a0, a1, a2, a3);
|
||||
"OK".to_string()
|
||||
|
||||
}
|
||||
80
src-tauri/src/iris_spectral/spectralbase/IS11_sensor/mod.rs
Normal file
@ -0,0 +1,80 @@
|
||||
use libc::{c_uchar, size_t};
|
||||
use std::slice;
|
||||
|
||||
use crate::serport::serport::*;
|
||||
use super::STRSensorInfo;
|
||||
|
||||
|
||||
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
|
||||
#[cfg_attr(target_os = "windows", link(name = "..\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022/is11lib", kind = "dylib"))]
|
||||
#[cfg_attr(target_os = "linux", link(name = "is11lib", kind = "dylib"))]
|
||||
// #[link(name = "../myis11/project/is11/cmake-build-release-visual-studio-2022/is11lib",kind = "dylib")]
|
||||
|
||||
extern "C" {
|
||||
pub fn Set_Serial_FUN(writefunc:SerialWrite,readfunc:SerialWrite);
|
||||
pub fn abs1(input: i32) -> i32;
|
||||
pub fn test();
|
||||
pub fn IS11SensorInit() -> i32;
|
||||
pub fn Get_SensorInfo() -> STRSensorInfo;
|
||||
pub fn IS11OptSnenser(percent:i32) -> i32;
|
||||
pub fn IS11GetData(outdata: *mut u16, shuttertime: i32) -> i32;
|
||||
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn serialsenddata(data: *mut c_uchar, length: size_t) -> size_t {
|
||||
// 处理数据
|
||||
let data_slice = slice::from_raw_parts(data, length as usize).to_vec();
|
||||
// data_slice转换为Vec<u8>
|
||||
|
||||
// 打印数据
|
||||
// for byte in data_slice.clone() {
|
||||
// print!("{:02X} ", byte);
|
||||
// }
|
||||
// println!();
|
||||
sendtoprot(data_slice);
|
||||
length
|
||||
}
|
||||
use core::ptr;
|
||||
pub unsafe extern "C" fn serialreaddate(data: *mut c_uchar, length: size_t) -> size_t {
|
||||
|
||||
let dataout=readforport();
|
||||
let length1: usize = dataout.len();
|
||||
// 将结果复制给c_uchar
|
||||
// for byte in dataout.clone() {
|
||||
// print!("{:02X} ", byte);
|
||||
// }
|
||||
// println!();
|
||||
|
||||
ptr::copy_nonoverlapping(dataout.as_ptr(), data, length1);
|
||||
// println!("{:?}",data);
|
||||
length1
|
||||
}
|
||||
|
||||
pub fn is11_init() -> i32 {
|
||||
unsafe {
|
||||
Set_Serial_FUN(Some(serialsenddata), Some(serialreaddate));
|
||||
IS11SensorInit()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is11_get_sensor_info() -> STRSensorInfo {
|
||||
unsafe { Get_SensorInfo() }
|
||||
}
|
||||
|
||||
pub fn _is11_opt_snenser(percent: i32) -> i32 {
|
||||
unsafe { IS11OptSnenser(percent) }
|
||||
}
|
||||
|
||||
pub fn is11_get_data(shuttertime: i32) -> Vec<u16> {
|
||||
let mut outdata: Vec<u16> = vec![0; 2048];
|
||||
|
||||
unsafe {
|
||||
|
||||
let len = IS11GetData(outdata.as_mut_ptr(), shuttertime);
|
||||
outdata.truncate(len as usize);
|
||||
|
||||
|
||||
}
|
||||
|
||||
outdata
|
||||
}
|
||||
94
src-tauri/src/iris_spectral/spectralbase/IS3_sensor/mod.rs
Normal file
@ -0,0 +1,94 @@
|
||||
use libc::{c_uchar, size_t};
|
||||
use std::slice;
|
||||
|
||||
use crate::serport::serport::*;
|
||||
use super::STRSensorInfo;
|
||||
|
||||
//void IS3SetShutterOpen(int isopen);
|
||||
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
|
||||
#[cfg_attr(target_os = "windows", link(name = "..\\myis11\\project\\is3\\cmake-build-debug-visual-studio/iris_is3lib", kind = "dylib"))]
|
||||
#[cfg_attr(target_os = "linux", link(name = "iris_is3lib", kind = "dylib"))]
|
||||
// #[link(
|
||||
// name = "..\\myis11\\project\\is3\\cmake-build-debug-visual-studio/iris_is3lib",
|
||||
// kind = "dylib"
|
||||
// )]
|
||||
extern "C" {
|
||||
pub fn IS3Set_Serial_FUN(writefunc:SerialWrite,readfunc:SerialWrite);
|
||||
pub fn IS3SensorInit() -> i32;
|
||||
pub fn IS3Get_SensorInfo() -> STRSensorInfo;
|
||||
pub fn IS3OptSnenser(percent:i32) -> i32;
|
||||
pub fn IS3GetData(outdata: *mut u16, shuttertime: i32) -> i32;
|
||||
pub fn IS3SetWeaveLenthCoeff(a:*mut f64,length:i32) -> i32;
|
||||
pub fn IS3SetShutterOpen(isopen: i32) ;
|
||||
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn serialsenddata(data: *mut c_uchar, length: size_t) -> size_t {
|
||||
// 处理数据
|
||||
let data_slice = slice::from_raw_parts(data, length as usize).to_vec();
|
||||
// data_slice转换为Vec<u8>
|
||||
|
||||
// 打印数据
|
||||
// for byte in data_slice.clone() {
|
||||
// print!("{:02X} ", byte);
|
||||
// }
|
||||
// println!();
|
||||
sendtoprot(data_slice);
|
||||
length
|
||||
}
|
||||
use core::ptr;
|
||||
pub unsafe extern "C" fn serialreaddate(data: *mut c_uchar, length: size_t) -> size_t {
|
||||
|
||||
let dataout=readforport();
|
||||
let length1: usize = dataout.len();
|
||||
// 将结果复制给c_uchar
|
||||
// for byte in dataout.clone() {
|
||||
// print!("{:02X} ", byte);
|
||||
// }
|
||||
// println!();
|
||||
|
||||
ptr::copy_nonoverlapping(dataout.as_ptr(), data, length1);
|
||||
// println!("{:?}",data);
|
||||
length1
|
||||
}
|
||||
|
||||
pub fn is3_init() -> i32 {
|
||||
unsafe {
|
||||
IS3Set_Serial_FUN(Some(serialsenddata), Some(serialreaddate));
|
||||
IS3SensorInit()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is3_get_sensor_info() -> STRSensorInfo {
|
||||
unsafe { IS3Get_SensorInfo() }
|
||||
}
|
||||
|
||||
pub fn is3_opt_snenser(percent: i32) -> i32 {
|
||||
unsafe { IS3OptSnenser(percent) }
|
||||
}
|
||||
|
||||
pub fn is3_get_data(shuttertime: i32) -> Vec<u16> {
|
||||
let mut outdata: Vec<u16> = vec![0; 2048];
|
||||
|
||||
unsafe {
|
||||
|
||||
let len = IS3GetData(outdata.as_mut_ptr(), shuttertime);
|
||||
outdata.truncate(len as usize);
|
||||
|
||||
|
||||
}
|
||||
|
||||
outdata
|
||||
}
|
||||
pub fn is3_set_shutter_open(isopen: i32) {
|
||||
unsafe { IS3SetShutterOpen(isopen) }
|
||||
}
|
||||
|
||||
pub fn is3_set_weave_length_coeff(a: Vec<f64>) -> i32 {
|
||||
let mut a = a.clone();
|
||||
let a_ptr = a.as_mut_ptr();
|
||||
let length = a.len() as i32;
|
||||
println!("a_ptr: {:?}", a_ptr);
|
||||
println!("length: {:?}", length);
|
||||
unsafe { IS3SetWeaveLenthCoeff(a_ptr, length) }
|
||||
}
|
||||
255
src-tauri/src/iris_spectral/spectralbase/mod.rs
Normal file
@ -0,0 +1,255 @@
|
||||
|
||||
use libc::{c_uchar,c_char,c_long,c_float, size_t};
|
||||
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
mod IS3_sensor;
|
||||
mod IS11_sensor;
|
||||
// 定义emun 不同光谱仪
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Senortype {
|
||||
IS11,
|
||||
IS1,
|
||||
IS2,
|
||||
OSIF,
|
||||
IS3
|
||||
|
||||
}
|
||||
|
||||
//全局变量 传感器类型 用lazy_static宏定义 原子变量
|
||||
lazy_static! {
|
||||
static ref SENSORTYPE: Arc<Mutex<Senortype>> = Arc::new(Mutex::new(Senortype::IS3));
|
||||
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct STRSensorInfo {
|
||||
pub SensorName: [c_char; 100],
|
||||
pub maxValue: c_long,
|
||||
pub BandNum: c_long,
|
||||
pub serialnumber: [c_char; 100],
|
||||
pub a1: c_float,
|
||||
pub a2: c_float,
|
||||
pub a3: c_float,
|
||||
pub a4: c_float,
|
||||
pub issensorinit: c_uchar,
|
||||
}
|
||||
|
||||
impl Default for STRSensorInfo {
|
||||
fn default() -> Self {
|
||||
STRSensorInfo {
|
||||
SensorName: [0; 100],
|
||||
maxValue: 0,
|
||||
BandNum: 0,
|
||||
serialnumber: [0; 100],
|
||||
a1: 0.0,
|
||||
a2: 0.0,
|
||||
a3: 0.0,
|
||||
a4: 0.0,
|
||||
issensorinit: 0,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref SENSOR_INFO: Arc<Mutex<STRSensorInfo>> = Arc::new(Mutex::new(STRSensorInfo::default()));
|
||||
|
||||
}
|
||||
|
||||
pub fn sensor_set_sensor_type(senortype:String)
|
||||
{
|
||||
let mut data = SENSORTYPE.lock().unwrap();
|
||||
match senortype.as_str() {
|
||||
"IS11" => *data = Senortype::IS11,
|
||||
"IS1" => *data = Senortype::IS1,
|
||||
"IS2" => *data = Senortype::IS2,
|
||||
"OSIF" => *data = Senortype::OSIF,
|
||||
"IS3" => *data = Senortype::IS3,
|
||||
_ => *data = Senortype::IS11,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn abs1(input: i32) -> i32
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
pub fn test()
|
||||
{
|
||||
|
||||
}
|
||||
pub fn sensor_init() -> i32
|
||||
{
|
||||
let senortype = SENSORTYPE.lock().unwrap();
|
||||
match *senortype {
|
||||
Senortype::IS11 => {
|
||||
unsafe {
|
||||
IS11_sensor::Set_Serial_FUN(Some(IS11_sensor::serialsenddata), Some(IS11_sensor::serialreaddate));
|
||||
return IS11_sensor::IS11SensorInit();
|
||||
}
|
||||
|
||||
},
|
||||
Senortype::IS3 => {
|
||||
unsafe {
|
||||
IS3_sensor::IS3Set_Serial_FUN(Some(IS3_sensor::serialsenddata), Some(IS3_sensor::serialreaddate));
|
||||
return IS3_sensor::IS3SensorInit();
|
||||
}
|
||||
|
||||
},
|
||||
_ => {
|
||||
return 0;
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
pub fn sensor_get_sensor_info() -> STRSensorInfo{
|
||||
let senortype = SENSORTYPE.lock().unwrap();
|
||||
let mut Sensorinfo= SENSOR_INFO.lock().unwrap();
|
||||
match *senortype {
|
||||
Senortype::IS11 => {
|
||||
unsafe {
|
||||
let info = IS11_sensor::Get_SensorInfo();
|
||||
*Sensorinfo = info.clone();
|
||||
return info;
|
||||
}
|
||||
|
||||
},
|
||||
Senortype::IS3 => {
|
||||
unsafe {
|
||||
let info = IS3_sensor::IS3Get_SensorInfo();
|
||||
*Sensorinfo = info.clone();
|
||||
return info;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
_ => {
|
||||
return STRSensorInfo::default();
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
pub fn sensor_opt_sensor(percent:i32) -> i32{
|
||||
let senortype = SENSORTYPE.lock().unwrap();
|
||||
match *senortype {
|
||||
Senortype::IS11 => {
|
||||
unsafe {
|
||||
return IS11_sensor::IS11OptSnenser(percent);
|
||||
}
|
||||
|
||||
},
|
||||
Senortype::IS3 => {
|
||||
unsafe {
|
||||
return IS3_sensor::IS3OptSnenser(percent);
|
||||
}
|
||||
|
||||
},
|
||||
_ => {
|
||||
return 0;
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
pub fn sensor_get_data_base(outdata: *mut u16, shuttertime: i32) -> i32
|
||||
{
|
||||
let senortype = SENSORTYPE.lock().unwrap();
|
||||
match *senortype {
|
||||
Senortype::IS11 => {
|
||||
unsafe {
|
||||
return IS11_sensor::IS11GetData(outdata, shuttertime);
|
||||
}
|
||||
|
||||
},
|
||||
Senortype::IS3 => {
|
||||
unsafe {
|
||||
return IS3_sensor::IS3GetData(outdata, shuttertime);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_ => {
|
||||
return 0;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn sensor_get_data(shuttertime: i32) -> Vec<u16> {
|
||||
let sensor_info= SENSOR_INFO.lock().unwrap();
|
||||
let bandSum = sensor_info.BandNum as usize;
|
||||
let mut outdata: Vec<u16> = vec![0; bandSum];
|
||||
|
||||
unsafe {
|
||||
|
||||
let len = sensor_get_data_base(outdata.as_mut_ptr(), shuttertime);
|
||||
outdata.truncate(len as usize);
|
||||
|
||||
|
||||
|
||||
}
|
||||
// polynomial_smooth_u16( outdata ,7)
|
||||
outdata
|
||||
}
|
||||
|
||||
pub fn set_sensor_weave_length_coeff(a: Vec<f64>) -> i32 {
|
||||
let senortype = SENSORTYPE.lock().unwrap();
|
||||
match *senortype {
|
||||
Senortype::IS11 => {
|
||||
|
||||
0
|
||||
|
||||
},
|
||||
Senortype::IS3 => {
|
||||
IS3_sensor::is3_set_weave_length_coeff(a);
|
||||
0
|
||||
|
||||
|
||||
},
|
||||
_ => {
|
||||
return 0;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sensor_set_shutter_open(isopen:i32) {
|
||||
let senortype = SENSORTYPE.lock().unwrap();
|
||||
match *senortype {
|
||||
Senortype::IS11 => {
|
||||
unsafe {
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
Senortype::IS3 => {
|
||||
unsafe {
|
||||
IS3_sensor::IS3SetShutterOpen(isopen);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
_ => {
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
467
src-tauri/src/iris_spectral/spectralserver.rs
Normal file
@ -0,0 +1,467 @@
|
||||
use super::spectralbase;
|
||||
use super::spectralbase::*;
|
||||
use super::super::mydefine::*;
|
||||
use lazy_static::lazy_static;
|
||||
use chrono::{self, Datelike, Timelike};
|
||||
use std::thread;
|
||||
use std::fs::File;
|
||||
use std::mem;
|
||||
use std::path::Path;
|
||||
use std::io::Read;
|
||||
#[derive(PartialEq)]
|
||||
enum WorkStat {
|
||||
IDLE,
|
||||
WOKING,
|
||||
STOP,
|
||||
OPTING,
|
||||
|
||||
}
|
||||
|
||||
|
||||
use std::vec;
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
struct is11_dev_data {
|
||||
sensor_info: super::spectralbase::STRSensorInfo,
|
||||
shuttertime: i32,
|
||||
stat: WorkStat,
|
||||
percent: i32,
|
||||
workname: String,
|
||||
hasdark: bool,
|
||||
hasflat: bool,
|
||||
removedark: bool,
|
||||
computeflat: bool,
|
||||
average_number_data: u32,
|
||||
average_number_dark: u32,
|
||||
average_number_flat: u32,
|
||||
has_CalidataUP: bool,
|
||||
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref DEV_STAT: Arc<Mutex<is11_dev_data>> = Arc::new(Mutex::new(is11_dev_data {
|
||||
sensor_info: super::spectralbase::STRSensorInfo::default(),
|
||||
shuttertime: 0,
|
||||
stat: WorkStat::IDLE,
|
||||
percent: 0,
|
||||
workname: "noting".to_string(),
|
||||
hasdark: false,
|
||||
hasflat: false,
|
||||
removedark: false,
|
||||
computeflat: true,
|
||||
average_number_data: 1,
|
||||
average_number_dark: 10,
|
||||
average_number_flat: 10,
|
||||
has_CalidataUP: false,
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
// lazy_static! {
|
||||
// static ref DATA: Arc<Mutex<Vec<u16>>> = Arc::new(Mutex::new(Vec::new()));
|
||||
// }
|
||||
|
||||
lazy_static! {
|
||||
static ref DATA_IS11: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
||||
static ref DARK_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
||||
static ref FLAT_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
||||
static ref CALIDATAUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
||||
static ref CALIOFFSETUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn is11_get_sensor_info() -> STRSensorInfo {
|
||||
return super::spectralbase::sensor_get_sensor_info();
|
||||
}
|
||||
pub fn is11_init(){
|
||||
super::spectralbase::sensor_init();
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let sensorinfo= is11_get_sensor_info();
|
||||
dev_stat.sensor_info=sensorinfo;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn get_shuttertime() -> i32 {
|
||||
let dev_stat=DEV_STAT.lock().unwrap();
|
||||
return dev_stat.shuttertime;
|
||||
}
|
||||
|
||||
|
||||
pub fn opt_sensor(percent: i32) -> i32 {
|
||||
|
||||
|
||||
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
if dev_stat.stat != WorkStat::IDLE {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_stat.stat=WorkStat::OPTING;
|
||||
dev_stat.percent=0;
|
||||
dev_stat.workname="opting".to_string();
|
||||
drop(dev_stat); //释放锁
|
||||
thread::spawn(move || {
|
||||
|
||||
let shuttertime= super::spectralbase::sensor_opt_sensor(90); //多线程设置曝光时间
|
||||
let mut dev_statnow=DEV_STAT.lock().unwrap();
|
||||
dev_statnow.stat=WorkStat::IDLE;
|
||||
dev_statnow.shuttertime=shuttertime;
|
||||
dev_statnow.workname="finish".to_string();
|
||||
dev_statnow.percent=100;
|
||||
dev_statnow.hasdark=false;
|
||||
dev_statnow.hasflat=false;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn get_now_stat()->(String,String,i32){
|
||||
|
||||
|
||||
let dev_stat=DEV_STAT.lock().unwrap();
|
||||
match dev_stat.stat {
|
||||
WorkStat::IDLE => {
|
||||
return ("finish".to_string(),dev_stat.workname.clone(),100);
|
||||
},
|
||||
WorkStat::WOKING => {
|
||||
return ("working".to_string(),dev_stat.workname.clone(),dev_stat.percent);
|
||||
},
|
||||
WorkStat::STOP => {
|
||||
return ("finish".to_string(),dev_stat.workname.clone(),dev_stat.percent);
|
||||
},
|
||||
WorkStat::OPTING => {
|
||||
return ("opting".to_string(),dev_stat.workname.clone(),dev_stat.percent);
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn collect(shuttertime:u32,removedark:bool,computeflat:bool){
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
if dev_stat.stat != WorkStat::IDLE {
|
||||
return ;
|
||||
}
|
||||
|
||||
let averagenumber=dev_stat.average_number_data;
|
||||
dev_stat.stat=WorkStat::WOKING;
|
||||
dev_stat.percent=0;
|
||||
|
||||
dev_stat.workname="采集中".to_string();
|
||||
let bandsunm=dev_stat.sensor_info.BandNum as usize;
|
||||
drop(dev_stat); //释放锁
|
||||
thread::spawn(move || {
|
||||
|
||||
|
||||
let mut datasum:Vec<u32>=vec![0;bandsunm];
|
||||
for _i in 0..averagenumber {
|
||||
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
|
||||
for i in 0..bandsunm {
|
||||
datasum[i]=datasum[i]+data[i] as u32;
|
||||
}
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let info=format!("采集中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
|
||||
dev_stat.workname=info;
|
||||
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
|
||||
drop(dev_stat); //释放锁
|
||||
|
||||
|
||||
}
|
||||
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let _lenth=data.len();
|
||||
println!("data len={}",_lenth);
|
||||
let mut tempis11data=IS11DataStruct::default();
|
||||
for i in 0.._lenth {
|
||||
tempis11data.data[i]=data[i] as f32;
|
||||
}
|
||||
// 获取当前时间
|
||||
let now = chrono::Local::now();
|
||||
tempis11data.year=(now.year()-2000) as u8;
|
||||
tempis11data.month=now.month() as u8;
|
||||
tempis11data.day=now.day() as u8;
|
||||
tempis11data.hour=now.hour() as u8;
|
||||
tempis11data.minute=now.minute() as u8;
|
||||
tempis11data.second=now.second() as u8;
|
||||
tempis11data.shutter_time=shuttertime;
|
||||
tempis11data.index=0;
|
||||
tempis11data.datatype=0;
|
||||
|
||||
let mut data1=DATA_IS11.lock().unwrap();
|
||||
let darkdata=DARK_DATA.lock().unwrap();
|
||||
*data1=tempis11data;
|
||||
if removedark && dev_stat.hasdark {
|
||||
|
||||
for i in 0.._lenth {
|
||||
data1.data[i]=data1.data[i]-darkdata.data[i];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if computeflat && dev_stat.hasflat {
|
||||
let flatdata=FLAT_DATA.lock().unwrap();
|
||||
for i in 0.._lenth {
|
||||
|
||||
let temp=flatdata.data[i]-darkdata.data[i];
|
||||
if temp<=0.0 {
|
||||
data1.data[i]=10000.0;
|
||||
}else{
|
||||
data1.data[i]=data1.data[i]/temp*10000.0;
|
||||
}
|
||||
if data1.data[i]<0.0 {
|
||||
data1.data[i]=0.0;
|
||||
|
||||
}
|
||||
if data1.data[i]>15000.0 {
|
||||
data1.data[i]=15000.0;
|
||||
}
|
||||
|
||||
// data1.data[i]=data1.data[i]/(flatdata.data[i]-darkdata.data[i])*10000.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dev_stat.stat=WorkStat::IDLE;
|
||||
dev_stat.percent=100;
|
||||
dev_stat.workname="finish".to_string();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn collcect_dark(shuttertime:u32)
|
||||
{
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
if dev_stat.stat != WorkStat::IDLE {
|
||||
return ;
|
||||
}
|
||||
let averagenumber=dev_stat.average_number_dark;
|
||||
dev_stat.stat=WorkStat::WOKING;
|
||||
dev_stat.percent=0;
|
||||
dev_stat.workname="采集Dark中".to_string();
|
||||
let bandsunm=dev_stat.sensor_info.BandNum as usize;
|
||||
drop(dev_stat); //释放锁
|
||||
thread::spawn(move || {
|
||||
let mut datasum:Vec<u32>=vec![0;bandsunm];
|
||||
sensor_set_shutter_open(0);
|
||||
for _i in 0..averagenumber {
|
||||
|
||||
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
|
||||
for i in 0..bandsunm {
|
||||
datasum[i]=datasum[i]+data[i] as u32;
|
||||
}
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let info=format!("采集Dark中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
|
||||
dev_stat.workname=info;
|
||||
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
|
||||
drop(dev_stat); //释放锁
|
||||
}
|
||||
sensor_set_shutter_open(1);
|
||||
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
|
||||
|
||||
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let _lenth=data.len();
|
||||
println!("data len={}",_lenth);
|
||||
let mut tempis11data=IS11DataStruct::default();
|
||||
for i in 0.._lenth {
|
||||
tempis11data.data[i]=data[i] as f32;
|
||||
}
|
||||
//获取当前时间
|
||||
let now = chrono::Local::now();
|
||||
tempis11data.year=(now.year()-2000) as u8;
|
||||
tempis11data.month=now.month() as u8;
|
||||
tempis11data.day=now.day() as u8;
|
||||
tempis11data.hour=now.hour() as u8;
|
||||
tempis11data.minute=now.minute() as u8;
|
||||
tempis11data.second=now.second() as u8;
|
||||
tempis11data.shutter_time=shuttertime;
|
||||
tempis11data.index=0;
|
||||
tempis11data.datatype=0;
|
||||
|
||||
let mut data1=DARK_DATA.lock().unwrap();
|
||||
*data1=tempis11data;
|
||||
dev_stat.stat=WorkStat::IDLE;
|
||||
dev_stat.percent=100;
|
||||
dev_stat.workname="finish".to_string();
|
||||
dev_stat.hasdark=true;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub fn collcect_flat(shuttertime:u32)
|
||||
{
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
if dev_stat.stat != WorkStat::IDLE {
|
||||
return ;
|
||||
}
|
||||
let averagenumber=dev_stat.average_number_flat;
|
||||
dev_stat.stat=WorkStat::WOKING;
|
||||
dev_stat.percent=0;
|
||||
dev_stat.workname="采集中".to_string();
|
||||
let bandsunm=dev_stat.sensor_info.BandNum as usize;
|
||||
drop(dev_stat); //释放锁
|
||||
thread::spawn(move || {
|
||||
let mut datasum:Vec<u32>=vec![0;bandsunm];
|
||||
for _i in 0..averagenumber {
|
||||
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
|
||||
for i in 0..bandsunm {
|
||||
datasum[i]=datasum[i]+data[i] as u32;
|
||||
}
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let info=format!("采集白板中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
|
||||
dev_stat.workname=info;
|
||||
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
|
||||
drop(dev_stat); //释放锁
|
||||
}
|
||||
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
|
||||
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
let _lenth=data.len();
|
||||
println!("data len={}",_lenth);
|
||||
let mut tempis11data=IS11DataStruct::default();
|
||||
for i in 0.._lenth {
|
||||
tempis11data.data[i]=data[i] as f32;
|
||||
}
|
||||
//获取当前时间
|
||||
let now = chrono::Local::now();
|
||||
tempis11data.year=(now.year()-2000) as u8;
|
||||
tempis11data.month=now.month() as u8;
|
||||
tempis11data.day=now.day() as u8;
|
||||
tempis11data.hour=now.hour() as u8;
|
||||
tempis11data.minute=now.minute() as u8;
|
||||
tempis11data.second=now.second() as u8;
|
||||
tempis11data.shutter_time=shuttertime;
|
||||
tempis11data.index=0;
|
||||
tempis11data.datatype=0;
|
||||
|
||||
let mut data1=FLAT_DATA.lock().unwrap();
|
||||
*data1=tempis11data;
|
||||
dev_stat.stat=WorkStat::IDLE;
|
||||
dev_stat.percent=100;
|
||||
dev_stat.workname="finish".to_string();
|
||||
dev_stat.hasflat=true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
pub fn get_data()->IS11DataStruct{
|
||||
let data1=DATA_IS11.lock().unwrap();
|
||||
return data1.clone();
|
||||
}
|
||||
pub fn get_data_flat()->IS11DataStruct{
|
||||
let data1=FLAT_DATA.lock().unwrap();
|
||||
return data1.clone();
|
||||
}
|
||||
pub fn get_data_dark()->IS11DataStruct{
|
||||
let data1=DARK_DATA.lock().unwrap();
|
||||
return data1.clone();
|
||||
}
|
||||
pub fn get_is_computeref()->bool{
|
||||
let dev_stat=DEV_STAT.lock().unwrap();
|
||||
return dev_stat.computeflat;
|
||||
}
|
||||
|
||||
pub fn set_shutter_time(shuttertime:u32){
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
dev_stat.shuttertime=shuttertime as i32;
|
||||
dev_stat.hasdark=false;
|
||||
dev_stat.hasflat=false;
|
||||
}
|
||||
|
||||
|
||||
pub fn set_average_number(arverage_number_data:u32,arverage_number_dark:u32,arverage_number_flat:u32){
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
dev_stat.average_number_data=arverage_number_data;
|
||||
dev_stat.average_number_dark=arverage_number_dark;
|
||||
dev_stat.average_number_flat=arverage_number_flat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn calibrate_file(orgdata: &IS11DataStruct) -> IS11DataStruct {
|
||||
let dev_stat=DEV_STAT.lock().unwrap();
|
||||
if !dev_stat.has_CalidataUP {
|
||||
return orgdata.clone();
|
||||
}
|
||||
drop(dev_stat);
|
||||
;
|
||||
let calidata=CALIDATAUP.lock().unwrap();
|
||||
let offsetdata=CALIOFFSETUP.lock().unwrap();
|
||||
|
||||
let mut data = IS11DataStruct::default();
|
||||
let collect_gaindb = orgdata.temprature[0];
|
||||
let collect_shutter = orgdata.shutter_time;
|
||||
let cali_gaindb = calidata.temprature[0];
|
||||
let cali_shutter = calidata.shutter_time;
|
||||
//db 转系数
|
||||
let collect_gain = 10.0_f32.powf(collect_gaindb / 20.0);
|
||||
let cali_gain = 10.0_f32.powf(cali_gaindb / 20.0);
|
||||
//计算增益
|
||||
let Scale_gain = cali_gain / collect_gain;
|
||||
let Scale_shutter = cali_shutter as f32/ collect_shutter as f32;
|
||||
let SCale = Scale_gain * Scale_shutter as f32;
|
||||
let len = orgdata.data.len();
|
||||
for i in 0..len {
|
||||
data.data[i] = orgdata.data[i] * SCale * calidata.data[i]+offsetdata.data[i];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
pub fn load_all_calibrate_file(filepath: String) -> String {
|
||||
let file_path = Path::new(&filepath);
|
||||
if file_path.exists() {
|
||||
let mut up_gain_data=CALIDATAUP.lock().unwrap();
|
||||
*up_gain_data=load_calibrate_file(file_path.to_str().unwrap().to_string()).unwrap();
|
||||
let mut dev_stat=DEV_STAT.lock().unwrap();
|
||||
dev_stat.has_CalidataUP=true;
|
||||
return "ok".to_string();
|
||||
} else {
|
||||
println!("文件不存在: {:?}", file_path);
|
||||
return "文件不存在".to_string();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fn load_calibrate_file(filepath: String) -> Result<IS11DataStruct, String> {
|
||||
let mut data = IS11DataStruct::default();
|
||||
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
|
||||
let mut file = File::open(filepath).unwrap();
|
||||
file.read_exact(&mut buffer).unwrap();
|
||||
unsafe {
|
||||
let ptr = &mut data as *mut IS11DataStruct as *mut u8;
|
||||
std::ptr::copy_nonoverlapping(buffer.as_ptr(), ptr, mem::size_of::<IS11DataStruct>());
|
||||
}
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
pub fn set_weave_coeff(specnumber: i32, a0: f64, a1: f64, a2: f64, a3: f64) -> String {
|
||||
let vecdata=vec![a0,a1,a2,a3];
|
||||
spectralbase::set_sensor_weave_length_coeff(vecdata);
|
||||
"ok".to_string()
|
||||
}
|
||||
|
||||
265
src-tauri/src/irisdatamanager/mod.rs
Normal file
@ -0,0 +1,265 @@
|
||||
use std::fmt::format;
|
||||
|
||||
use chrono::Datelike;
|
||||
use chrono::Timelike;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::myformatiris::structures::*;
|
||||
use crate::myformatiris::read::*;
|
||||
use crate::myformatiris::write::*;
|
||||
|
||||
|
||||
pub fn savecalibratefileIRIS(Gain:serde_json::Value,direction: bool, filepath: String, dndata: serde_json::Value, lampdata: serde_json::Value, devinfo: serde_json::Value) -> String {
|
||||
//输出 输入参数
|
||||
//println!("Gain: {:?}", Gain);
|
||||
// println!("direction: {:?}", direction);
|
||||
// println!("Filepath: {:?}", devinfo);
|
||||
// println!("DNData: {:?}", dndata);
|
||||
// println!("Lampdata: {:?}", lampdata);
|
||||
// println!("Devinfo: {:?}", devinfo);
|
||||
let mut oneirisdata:OneIRISData = OneIRISData::new();
|
||||
let mut spectraldatagain: SpectralData= SpectralData::new();
|
||||
spectraldatagain.name= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&"_".to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string()+&"_gain".to_string();
|
||||
spectraldatagain.sensor_id= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
|
||||
spectraldatagain.bands= devinfo["bands"].as_u64().unwrap_or(0) as u16;
|
||||
spectraldatagain.pixel_size=8;
|
||||
spectraldatagain.data_type=DATA_TYPE_FLOAT64;
|
||||
spectraldatagain.fiber_id=direction as u8;
|
||||
spectraldatagain.exposure=Gain["shutter_time"].as_u64().unwrap_or(0) as f64;
|
||||
spectraldatagain.gain=Gain["sensor_gain"].as_f64().unwrap_or(1.0) as f32;
|
||||
let datenow = chrono::Local::now();
|
||||
let nowtiem= TimeStruct {
|
||||
|
||||
time_zone:50,
|
||||
year:datenow.year() as u16,
|
||||
month:datenow.month() as u8,
|
||||
day:datenow.day() as u8,
|
||||
hour:datenow.hour() as u8,
|
||||
minute:datenow.minute() as u8,
|
||||
second:datenow.second() as u8,
|
||||
millisecond:datenow.timestamp_subsec_millis() as u16,
|
||||
};
|
||||
spectraldatagain.collection_time=nowtiem.clone();
|
||||
spectraldatagain.ground_type=Target_Spectral_Type_CaliFile_Gain;
|
||||
spectraldatagain.valid_flag=1;
|
||||
let spectraldatavec:Vec<f64>=Gain["Data"].as_array().unwrap_or(&vec![]).iter()
|
||||
.map(|x| x.as_f64().unwrap_or(0.0))
|
||||
.collect::<Vec<f64>>();
|
||||
spectraldatagain.Set_Spectral_Data(spectraldatavec, DATA_TYPE_FLOAT64);
|
||||
println!("spectraldata.name: {:?}", spectraldatagain.name);
|
||||
oneirisdata.spectral_data_section.push(spectraldatagain);
|
||||
let mut spectraldata_dn: SpectralData= SpectralData::new();
|
||||
spectraldata_dn.name= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&"_".to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string()+&"_dn".to_string();
|
||||
spectraldata_dn.sensor_id= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
|
||||
spectraldata_dn.bands= devinfo["bands"].as_u64().unwrap_or(0) as u16;
|
||||
spectraldata_dn.pixel_size=8;
|
||||
spectraldata_dn.fiber_id=direction as u8;
|
||||
spectraldata_dn.exposure=dndata["shutter_time"].as_u64().unwrap_or(0) as f64;
|
||||
spectraldata_dn.gain=dndata["gain"].as_f64().unwrap_or(1.0) as f32;
|
||||
spectraldata_dn.data_type=DATA_TYPE_FLOAT64;
|
||||
spectraldata_dn.collection_time=nowtiem.clone();
|
||||
spectraldata_dn.ground_type=Target_Spectral_Type_DN;
|
||||
spectraldata_dn.valid_flag=1;
|
||||
let spectraldatavec_dn:Vec<f64>=dndata["data"].as_array().unwrap_or(&vec![]).iter()
|
||||
.map(|x| x.as_f64().unwrap_or(0.0))
|
||||
.collect::<Vec<f64>>();
|
||||
spectraldata_dn.Set_Spectral_Data(spectraldatavec_dn, DATA_TYPE_FLOAT64);
|
||||
println!("spectraldata_dn.name: {:?}", spectraldata_dn.name);
|
||||
oneirisdata.spectral_data_section.push(spectraldata_dn);
|
||||
let mut spectraldata_lamp: SpectralData= SpectralData::new();
|
||||
let lampvalue= lampdata["value_lable"].as_str().unwrap_or("Unknown");
|
||||
let datalabel= lampdata["data_value"].as_str().unwrap_or("Unknown");
|
||||
spectraldata_lamp.name= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&"_".to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string()+&"_lamplable_".to_string()+&lampvalue.to_string()+&"_datalabel_".to_string()+&datalabel.to_string();
|
||||
spectraldata_lamp.sensor_id= devinfo["name"].as_str().unwrap_or("Unknown").to_string()+&devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
|
||||
let lampvalue_f64_vec= lampdata["data"].as_array().unwrap_or(&vec![]).iter()
|
||||
.map(|x| x.as_f64().unwrap_or(0.0))
|
||||
.collect::<Vec<f64>>();
|
||||
spectraldata_lamp.Set_Spectral_Data(lampvalue_f64_vec, DATA_TYPE_FLOAT64);
|
||||
spectraldata_lamp.ground_type=Target_LAMP_VALUE_SCALED;
|
||||
oneirisdata.spectral_data_section.push(spectraldata_lamp);
|
||||
|
||||
let spectraldata_devinfo= json!(
|
||||
{
|
||||
"info_type": "devinfo", // 0 for device info
|
||||
"sensor_id": devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string(),
|
||||
"wave_coeff": {
|
||||
"a1": devinfo["bochangxishu"]["a1"].as_f64().unwrap_or(0.0),
|
||||
"a2": devinfo["bochangxishu"]["a2"].as_f64().unwrap_or(0.0),
|
||||
"a3": devinfo["bochangxishu"]["a3"].as_f64().unwrap_or(0.0),
|
||||
"a4": devinfo["bochangxishu"]["a4"].as_f64().unwrap_or(0.0)
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
let environment_info= json!(
|
||||
{
|
||||
"info_type": "environment", // 1 for environment info
|
||||
"date": format!("{}-{:02}-{:02} {:02}:{:02}:{:02}",
|
||||
datenow.year(),
|
||||
datenow.month(),
|
||||
datenow.day(),
|
||||
datenow.hour(),
|
||||
datenow.minute(),
|
||||
datenow.second()
|
||||
),
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
/*
|
||||
let spectraldata_devinfo= json!(
|
||||
{
|
||||
"info_type": "infolist", // 0 for device info
|
||||
"info_number":3,
|
||||
"info_list": [
|
||||
{
|
||||
"info_type": "devinfo", // 0 for device info
|
||||
"sensor_id": "is30002",
|
||||
"bandnum": 2048,
|
||||
"wave_coeff": {
|
||||
"a1": 0.0,
|
||||
"a2": 0.0,
|
||||
"a3": 400,
|
||||
"a4": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"info_type": "environment", // 1 for gain info
|
||||
"date": "2000-01-00 00:00:00",
|
||||
//下面可选
|
||||
"humidity":90.0,
|
||||
"temperature":35.0 ,
|
||||
"gps":{
|
||||
"latitude":115.01,
|
||||
"longitude": 39.01,
|
||||
"altitude": 100.0
|
||||
},
|
||||
},
|
||||
{
|
||||
"info_type": "devinfo", // 0 for device info
|
||||
"sensor_id": "is20001",
|
||||
"bandnum": 512,
|
||||
"wave_coeff": {
|
||||
"a1": 0,
|
||||
"a2": 0.0,
|
||||
"a3":390,
|
||||
"a4": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
);
|
||||
*/
|
||||
|
||||
// spectraldata_devinfo.sensor_id=devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
|
||||
// spectraldata_devinfo.wave_coeff[0]=devinfo["bochangxishu"]["a1"].as_f64().unwrap_or(0.0);
|
||||
// spectraldata_devinfo.wave_coeff[1]=devinfo["bochangxishu"]["a2"].as_f64().unwrap_or(0.0);
|
||||
// spectraldata_devinfo.wave_coeff[2]=devinfo["bochangxishu"]["a3"].as_f64().unwrap_or(0.0);
|
||||
// spectraldata_devinfo.wave_coeff[3]=devinfo["bochangxishu"]["a4"].as_f64().unwrap_or(0.0);
|
||||
|
||||
oneirisdata.spectral_info_section.push(spectraldata_devinfo);
|
||||
oneirisdata.spectral_info_section.push(environment_info);
|
||||
|
||||
// 修复后的代码
|
||||
let filesave_date = format!("{}_{:04}{:02}{:02}",
|
||||
filepath, // 如果 filepath 是 String,这里会自动借用
|
||||
datenow.year(),
|
||||
datenow.month(),
|
||||
|
||||
datenow.day()
|
||||
);
|
||||
let filesavepath=filesave_date.clone()+".iris";
|
||||
|
||||
wirte_iris_data(&oneirisdata, &filesavepath);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"ok".to_string()
|
||||
|
||||
}
|
||||
|
||||
pub fn save_reflectance_to_iris(reflectance_data: serde_json::Value, devinfo: serde_json::Value, filepath: String) -> String {
|
||||
let mut oneirisdata: OneIRISData = OneIRISData::new();
|
||||
let mut spectraldata_reflectance: SpectralData = SpectralData::new();
|
||||
|
||||
let fileName = reflectance_data["fileName"].as_str().unwrap_or("Unknown").to_string();
|
||||
//将filename中的.替换为_ 并保存到新的变量里
|
||||
let fileName1 = fileName.replace(".", "_");
|
||||
spectraldata_reflectance.name = fileName1+&devinfo["name"].as_str().unwrap_or("Unknown").to_string() ;
|
||||
spectraldata_reflectance.sensor_id = devinfo["sensor_id"].as_str().unwrap_or("Unknown").to_string() ;
|
||||
// + &devinfo["serialnumber"].as_str().unwrap_or("Unknown").to_string();
|
||||
|
||||
let reflectance_values: Vec<f64> = reflectance_data["data"]
|
||||
.as_array()
|
||||
.unwrap_or(&vec![])
|
||||
.iter()
|
||||
.map(|x| x.as_f64().unwrap_or(0.0))
|
||||
.collect::<Vec<f64>>();
|
||||
|
||||
spectraldata_reflectance.bands = reflectance_values.len() as u16;
|
||||
spectraldata_reflectance.pixel_size = 8;
|
||||
spectraldata_reflectance.data_type = DATA_TYPE_FLOAT64;
|
||||
spectraldata_reflectance.fiber_id = 0;
|
||||
spectraldata_reflectance.exposure = 0.0;
|
||||
spectraldata_reflectance.gain = 0.0;
|
||||
|
||||
let datenow = chrono::Local::now();
|
||||
let nowtime = TimeStruct {
|
||||
time_zone: 50,
|
||||
year: datenow.year() as u16,
|
||||
month: datenow.month() as u8,
|
||||
day: datenow.day() as u8,
|
||||
hour: datenow.hour() as u8,
|
||||
minute: datenow.minute() as u8,
|
||||
second: datenow.second() as u8,
|
||||
millisecond: datenow.timestamp_subsec_millis() as u16,
|
||||
};
|
||||
spectraldata_reflectance.collection_time = nowtime.clone();
|
||||
spectraldata_reflectance.ground_type = Target_Spectral_Type_FlatRef;
|
||||
spectraldata_reflectance.valid_flag = 1;
|
||||
|
||||
spectraldata_reflectance.Set_Spectral_Data(reflectance_values, DATA_TYPE_FLOAT64);
|
||||
oneirisdata.spectral_data_section.push(spectraldata_reflectance);
|
||||
|
||||
let spectraldata_devinfo = json!({
|
||||
"info_type": "devinfo",
|
||||
"sensor_id": devinfo["sensor_id"].as_str().unwrap_or("Unknown").to_string(),
|
||||
"wave_coeff": {
|
||||
"a1": devinfo["bochangxishu"]["a0"].as_f64().unwrap_or(0.0),
|
||||
"a2": devinfo["bochangxishu"]["a1"].as_f64().unwrap_or(0.0),
|
||||
"a3": devinfo["bochangxishu"]["a2"].as_f64().unwrap_or(0.0),
|
||||
"a4": devinfo["bochangxishu"]["a3"].as_f64().unwrap_or(0.0)
|
||||
}
|
||||
});
|
||||
println!("spectraldata_devinfo: {:?}", spectraldata_devinfo);
|
||||
|
||||
let environment_info = json!({
|
||||
"info_type": "environment",
|
||||
"date": format!("{}-{:02}-{:02} {:02}:{:02}:{:02}",
|
||||
datenow.year(),
|
||||
datenow.month(),
|
||||
datenow.day(),
|
||||
datenow.hour(),
|
||||
datenow.minute(),
|
||||
datenow.second()
|
||||
)
|
||||
});
|
||||
|
||||
oneirisdata.spectral_info_section.push(spectraldata_devinfo);
|
||||
oneirisdata.spectral_info_section.push(environment_info);
|
||||
|
||||
match wirte_iris_data(&oneirisdata, &filepath) {
|
||||
Ok(_) => "ok".to_string(),
|
||||
Err(e) => format!("保存失败: {}", e)
|
||||
}
|
||||
}
|
||||
@ -2,16 +2,12 @@
|
||||
use core::str;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::io::{Write};
|
||||
// use std::sync::WaitTimeoutResult;
|
||||
use std::path::Path;
|
||||
use super::algorithm::interpolate_spline;
|
||||
use super::algorithm::sg_smooth;
|
||||
use std::mem;
|
||||
|
||||
use super::mylog::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
use super::serport::serport::*;
|
||||
use super::mydefine::*;
|
||||
|
||||
@ -19,7 +15,14 @@ use super::mydefine::*;
|
||||
|
||||
pub fn savecalibratefile_iris(gain: Vec<f32>, shutter: u32, direction: bool, filepath: String) -> String {
|
||||
let mut data = IS11DataStruct::default();
|
||||
data.data = gain.as_slice().try_into().unwrap();
|
||||
let lenthofgain = gain.len() ;
|
||||
for i in 0..lenthofgain {
|
||||
|
||||
|
||||
data.data[i] = gain[i];
|
||||
}
|
||||
|
||||
|
||||
data.shutter_time = shutter as u32;
|
||||
data.direction = if direction { 1 } else { 0 };
|
||||
data.datatype = 0x04;
|
||||
@ -328,8 +331,8 @@ if command == "\"get_data\"" {
|
||||
if datatype == 0x02 {
|
||||
let mut is11data = IS11DataStruct::default();
|
||||
unsafe {
|
||||
let mut is11data_ptr = &mut is11data as *mut IS11DataStruct;
|
||||
let mut ret_ptr = &mut ret[0] as *mut u8;
|
||||
let is11data_ptr = &mut is11data as *mut IS11DataStruct;
|
||||
let ret_ptr = &mut ret[0] as *mut u8;
|
||||
std::ptr::copy_nonoverlapping(
|
||||
ret_ptr,
|
||||
is11data_ptr as *mut u8,
|
||||
|
||||
@ -35,7 +35,9 @@ impl Default for STRSensorInfo {
|
||||
|
||||
|
||||
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
|
||||
#[link(name = "D:/06Learn/rust/tarui/myis11/project/is11/cmake-build-release-visual-studio-2022/is11lib",kind = "dylib")]
|
||||
#[cfg_attr(target_os = "windows", link(name = "..\\myis11\\project\\is11\\cmake-build-release-visual-studio-2022/is11lib", kind = "dylib"))]
|
||||
#[cfg_attr(target_os = "linux", link(name = "is11lib", kind = "dylib"))]
|
||||
//#[link(name = "../myis11/project/is11/cmake-build-release-visual-studio-2022/is11lib",kind = "dylib")]
|
||||
extern "C" {
|
||||
fn Set_Serial_FUN(writefunc:SerialWrite,readfunc:SerialWrite);
|
||||
fn abs1(input: i32) -> i32;
|
||||
|
||||
@ -1,31 +1,32 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
mod irisdatamanager;
|
||||
mod algorithm;
|
||||
mod mylog;
|
||||
mod serport;
|
||||
mod iris_spectral;
|
||||
mod irishypersptral;
|
||||
mod mydefine;
|
||||
mod comman1;
|
||||
mod jianzhiis11;
|
||||
mod myformatiris;
|
||||
use comman1::*;
|
||||
use algorithm::interpolate_spline;
|
||||
use algorithm::sg_smooth;
|
||||
use mydefine::*;
|
||||
|
||||
use iris_spectral::spectralbase::Senortype;
|
||||
use myformatiris::getoneirisfile;
|
||||
enum DevName {
|
||||
IRIS_IS11,
|
||||
JZ_IS11
|
||||
IRIS_SENSOR(Senortype),
|
||||
|
||||
}
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use tauri::api::version;
|
||||
use tauri::api::dir;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
//设置一个可修改的全局变量
|
||||
lazy_static! {
|
||||
static ref DEVNAME: Mutex<DevName> = Mutex::new(DevName::IRIS_IS11);
|
||||
static ref DEVNAME: Mutex<DevName> = Mutex::new(DevName::IRIS_SENSOR(Senortype::IS3));
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@ -43,6 +44,30 @@ lazy_static! {
|
||||
//println!("{}",readdatafromport(1000));
|
||||
String::from("Port set ok")
|
||||
}
|
||||
/* let data = {
|
||||
gain: Gain,
|
||||
direction: direction,
|
||||
filepath: Filepath,
|
||||
DNData: DNData,
|
||||
LampData: Lampdata,
|
||||
Devinfo: Devinfo
|
||||
} */
|
||||
#[tauri::command]
|
||||
fn savecalibratefileIRIS(Gain:serde_json::Value,direction: bool, filepath: String, dndata: serde_json::Value, lampdata: serde_json::Value, devinfo: serde_json::Value) -> String {
|
||||
//输出 输入参数
|
||||
// println!("Gain: {:?}", Gain);
|
||||
// println!("direction: {:?}", direction);
|
||||
// println!("Filepath: {:?}", devinfo);
|
||||
// println!("DNData: {:?}", dndata);
|
||||
// println!("Lampdata: {:?}", lampdata);
|
||||
// println!("Devinfo: {:?}", devinfo);
|
||||
|
||||
|
||||
|
||||
irisdatamanager::savecalibratefileIRIS(Gain, direction, filepath, dndata, lampdata, devinfo)
|
||||
|
||||
}
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
fn savecalibratefile(gain: Vec<f32>, shutter: u32, direction: bool, filepath: String) -> String {
|
||||
@ -51,7 +76,7 @@ fn savecalibratefile(gain: Vec<f32>, shutter: u32, direction: bool, filepath: St
|
||||
DevName::IRIS_IS11=>{
|
||||
return irishypersptral::savecalibratefile_iris(gain, shutter, direction, filepath);
|
||||
},
|
||||
DevName::JZ_IS11=>{
|
||||
DevName::IRIS_SENSOR(sensor_type)=>{
|
||||
return irishypersptral::savecalibratefile_iris(gain, shutter, direction, filepath);
|
||||
//return jianzhiis11::s(gain, shutter, direction, filepath);
|
||||
}
|
||||
@ -68,7 +93,7 @@ fn sendcalibratetodev(gain: Vec<f32>, shutter: u32, direction: u32) -> String {
|
||||
DevName::IRIS_IS11=>{
|
||||
return irishypersptral::sendcalibratetodev_iris(gain, shutter, direction !=0);
|
||||
},
|
||||
DevName::JZ_IS11=>{
|
||||
DevName::IRIS_SENSOR(sensor_type)=>{
|
||||
return irishypersptral::sendcalibratetodev_iris(gain, shutter, direction !=0);
|
||||
//return jianzhiis11::s(gain, shutter, direction, filepath);
|
||||
}
|
||||
@ -83,8 +108,18 @@ fn sendcalibratetodev(gain: Vec<f32>, shutter: u32, direction: u32) -> String {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
fn setdevtype(devtype: String)->String {
|
||||
let mut devname1 = DEVNAME.lock().unwrap();
|
||||
match devtype.as_str() {
|
||||
"IRIS-IS11" => *devname1 = DevName::IRIS_IS11,
|
||||
"IS3" => *devname1 = DevName::IRIS_SENSOR(Senortype::IS3),
|
||||
"IS11" => *devname1 = DevName::IRIS_SENSOR(Senortype::IS11),
|
||||
_ => *devname1 = DevName::IRIS_SENSOR(Senortype::IS3),
|
||||
}
|
||||
mylog::logtorust("set dev to ".to_string()+&devtype);
|
||||
return "ok".to_string();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -104,6 +139,17 @@ fn sendtoport(data: serde_json::Value, datatype: serde_json::Value) -> String {
|
||||
fn readformport(commanid: serde_json::Value, wait_time_json: serde_json::Value) -> String {
|
||||
irishypersptral::readformport_iris(commanid, wait_time_json)
|
||||
}
|
||||
#[tauri::command]
|
||||
fn set_weave_coeff(specnumber: i32, a0: f64, a1: f64, a2: f64, a3: f64) -> String {
|
||||
let devname=DEVNAME.lock().unwrap();
|
||||
match *devname{
|
||||
DevName::IRIS_SENSOR(sensor_type) =>{
|
||||
iris_spectral::set_weave_coeff(specnumber, a0, a1, a2, a3);
|
||||
} ,
|
||||
_ => {},
|
||||
}
|
||||
"OK".to_string()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn opencom(portname: serde_json::Value, baudrate: serde_json::Value) -> String {
|
||||
@ -115,7 +161,7 @@ fn readformport(commanid: serde_json::Value, wait_time_json: serde_json::Value)
|
||||
DevName::IRIS_IS11=>{
|
||||
baudrate =115200 as u32;
|
||||
},
|
||||
DevName::JZ_IS11=>{
|
||||
DevName::IRIS_SENSOR(sensor_type)=>{
|
||||
baudrate =921600 as u32;
|
||||
|
||||
}
|
||||
@ -144,8 +190,8 @@ fn sendtoport_andgetreturn(
|
||||
DevName::IRIS_IS11=>{
|
||||
return irishypersptral::sendtoport_andgetreturn_iris(data, datatype);
|
||||
},
|
||||
DevName::JZ_IS11=>{
|
||||
return jianzhiis11::sendtoport_andgetreturn(data, datatype);
|
||||
DevName::IRIS_SENSOR(sensor_type)=>{
|
||||
return iris_spectral::sendtoport_andgetreturn(data, datatype);
|
||||
}
|
||||
|
||||
}
|
||||
@ -154,6 +200,25 @@ fn sendtoport_andgetreturn(
|
||||
//jianzhiis11::sendtoport_andgetreturn(data, datatype)
|
||||
|
||||
}
|
||||
#[tauri::command]
|
||||
fn delete_file_by_path(filepath: String) -> String {
|
||||
let devname=DEVNAME.lock().unwrap();
|
||||
match *devname {
|
||||
DevName::IRIS_IS11=>{
|
||||
"delete_file_by_path_iris(filepath)".to_string()
|
||||
},
|
||||
DevName::IRIS_SENSOR(sensor_type)=>{
|
||||
return iris_spectral::delete_file(filepath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn save_reflectance_to_iris(reflectance_data: serde_json::Value, devinfo: serde_json::Value, filepath: String) -> String {
|
||||
irisdatamanager::save_reflectance_to_iris(reflectance_data, devinfo, filepath)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||
@ -179,10 +244,17 @@ fn main() {
|
||||
interpolate_spline,
|
||||
sg_smooth,
|
||||
savecalibratefile,
|
||||
savecalibratefileIRIS,
|
||||
sendcalibratetodev,
|
||||
setdevtype,
|
||||
set_weave_coeff,
|
||||
delete_file_by_path,
|
||||
algorithm::gaussian_filter_high,
|
||||
algorithm::interpolate_spline_at_points,
|
||||
algorithm::find_peek
|
||||
algorithm::find_peek,
|
||||
algorithm::compute_weave_coeff,
|
||||
getoneirisfile,
|
||||
save_reflectance_to_iris
|
||||
])
|
||||
.setup(|app| {
|
||||
|
||||
|
||||
16
src-tauri/src/myformatiris/mod.rs
Normal file
@ -0,0 +1,16 @@
|
||||
pub mod structures;
|
||||
pub mod read;
|
||||
pub mod write;
|
||||
|
||||
|
||||
pub use structures::{TimeStruct, SpectralData, ImageInfo, OneIRISData};
|
||||
pub use structures::*;
|
||||
pub use read::{read_time, read_spectral_data, read_image_info, read_iris_file};
|
||||
pub use write::*;
|
||||
|
||||
#[tauri::command]
|
||||
pub fn getoneirisfile(path:String)->OneIRISData{
|
||||
let returndata=read_iris_file(&path).unwrap();
|
||||
return returndata;
|
||||
|
||||
}
|
||||
343
src-tauri/src/myformatiris/read.rs
Normal file
@ -0,0 +1,343 @@
|
||||
use std::io::{Read, Result, BufReader};
|
||||
use std::fs::File;
|
||||
use std::convert::TryInto;
|
||||
use super::structures::{TimeStruct, SpectralData, ImageInfo, OneIRISData};
|
||||
// use serde::de::value;
|
||||
use serde_json::Value;
|
||||
pub fn read_time<R: Read>(reader: &mut R) -> Result<TimeStruct> {
|
||||
let mut buffer = [0u8; 10]; // Corrected buffer size to 10 bytes
|
||||
reader.read_exact(&mut buffer)?;
|
||||
|
||||
Ok(TimeStruct {
|
||||
time_zone: buffer[0] as i8,
|
||||
year: u16::from_le_bytes([buffer[1], buffer[2]]),
|
||||
month: buffer[3],
|
||||
day: buffer[4],
|
||||
hour: buffer[5],
|
||||
minute: buffer[6],
|
||||
second: buffer[7],
|
||||
millisecond: u16::from_le_bytes([buffer[8], buffer[9]]), // Indices 8 and 9 are correct for 10-byte buffer
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn read_image_info<R: Read>(reader: &mut R) -> Result<ImageInfo> {
|
||||
let mut info = ImageInfo::new();
|
||||
|
||||
// Read data length
|
||||
let mut len_buf = [0u8; 8];
|
||||
reader.read_exact(&mut len_buf)?;
|
||||
info.data_length = u64::from_le_bytes(len_buf);
|
||||
|
||||
// Read name (fixed size 100 bytes)
|
||||
let mut name_buf = [0u8; 100];
|
||||
reader.read_exact(&mut name_buf)?;
|
||||
info.name = String::from_utf8_lossy(&name_buf).trim_end_matches('\0').to_string();
|
||||
info.name = remove_after_null_split_once(info.name);
|
||||
|
||||
// Read collection time
|
||||
info.collection_time = read_time(reader)?;
|
||||
|
||||
// Read info type
|
||||
let mut type_buf = [0u8; 1];
|
||||
reader.read_exact(&mut type_buf)?;
|
||||
info.info_type = type_buf[0];
|
||||
let imagedatlenth= info.data_length as u64- 100-10-1; // Adjusted to account for the size of TimeStruct and info_type
|
||||
// Read image data
|
||||
info.image_data.resize(imagedatlenth as usize, 0);
|
||||
reader.read_exact(&mut info.image_data)?;
|
||||
|
||||
Ok(info)
|
||||
}
|
||||
|
||||
pub fn read_iris_file(path: &str) -> Result<OneIRISData> {
|
||||
let file = File::open(path)?;
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
// Read and verify magic number
|
||||
// let mut magic = [0u8; 4];
|
||||
// reader.read_exact(&mut magic)?;
|
||||
// if magic != [0x49, 0x52, 0x49, 0x53] { // "IRIS" in ASCII
|
||||
// return Err(std::io::Error::new(
|
||||
// std::io::ErrorKind::InvalidData,
|
||||
// "Not a valid IRIS file"
|
||||
// ));
|
||||
// }
|
||||
|
||||
let mut iris_data = OneIRISData::new();
|
||||
|
||||
// // Read file version
|
||||
// let mut version = [0u8; 2];
|
||||
// reader.read_exact(&mut version)?;
|
||||
|
||||
// Read sections until EOF
|
||||
loop {
|
||||
let mut section_header = [0u8; 12]; // type (4) + length (8)
|
||||
if reader.read_exact(&mut section_header).is_err() {
|
||||
break; // EOF reached
|
||||
}
|
||||
|
||||
let section_type = u32::from_le_bytes(section_header[0..4].try_into().unwrap());
|
||||
let section_length = u64::from_le_bytes(section_header[4..12].try_into().unwrap());
|
||||
|
||||
match section_type {
|
||||
0x00FF00FF => { // Spectral data section
|
||||
let count = read_section_count(&mut reader)?;
|
||||
let mut data = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
data.push(read_spectral_data(&mut reader)?);
|
||||
}
|
||||
iris_data.spectral_data_section = data;
|
||||
},
|
||||
0xFF00FF00 => { // Spectral info section
|
||||
let count = read_section_count(&mut reader)?;
|
||||
let mut data = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
let mut tempbuffer = [0u8; 3]; // Adjust size as needed
|
||||
reader.read_exact(&mut tempbuffer)?;
|
||||
let lenth = u16::from_le_bytes([tempbuffer[0],tempbuffer[1]]) as usize;
|
||||
let datatype= u8::from_le_bytes([tempbuffer[2]]);
|
||||
let mut tempvector = vec![0u8; lenth];
|
||||
reader.read_exact(&mut tempvector)?;
|
||||
// Convert to String
|
||||
let json_string = String::from_utf8(tempvector).unwrap_or_default();
|
||||
let json_string = json_string.trim_end_matches('\0').to_string();
|
||||
//print!("JSON String: {}", json_string);
|
||||
let json:Value = match serde_json::from_str(&json_string){
|
||||
Ok(json) => json,
|
||||
Err(e) => {
|
||||
eprintln!("Error parsing JSON: {}", e);
|
||||
continue; // Skip this entry if parsing fails
|
||||
}
|
||||
}; // Handle parsing error gracefully
|
||||
|
||||
//判断json["info_type"]是否存在
|
||||
if !json.get("info_type").is_some() {
|
||||
eprintln!("JSON does not contain 'info_type': {}", json_string);
|
||||
continue; // Skip this entry if "info_type" is missing
|
||||
}
|
||||
/* {
|
||||
"info_type": "infolist", // 0 for device info
|
||||
"info_number":3,
|
||||
"info_list": [
|
||||
{
|
||||
"info_type": "devinfo", // 0 for device info
|
||||
"sensor_id": "is30002",
|
||||
"bandnum": 2048,
|
||||
"wave_coeff": {
|
||||
"a1": 0.0,
|
||||
"a2": 0.0,
|
||||
"a3": 400,
|
||||
"a4": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"info_type": "environment", // 1 for gain info
|
||||
"date": "2000-01-00 00:00:00",
|
||||
//下面可选
|
||||
"humidity":90.0,
|
||||
"temperature":35.0 ,
|
||||
"gps":{
|
||||
"latitude":115.01,
|
||||
"longitude": 39.01,
|
||||
"altitude": 100.0
|
||||
},
|
||||
},
|
||||
{
|
||||
"info_type": "devinfo", // 0 for device info
|
||||
"sensor_id": "is20001",
|
||||
"bandnum": 512,
|
||||
"wave_coeff": {
|
||||
"a1": 0,
|
||||
"a2": 0.0,
|
||||
"a3":390,
|
||||
"a4": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
} */
|
||||
//如果info_type是infolist 则需要逐个解析
|
||||
if json.get("info_type").and_then(Value::as_str) == Some("infolist") {
|
||||
let info_number = json.get("info_number").and_then(Value::as_u64).unwrap_or(0) as usize;
|
||||
for i in 0 ..info_number{
|
||||
//将对应的info加入到data中
|
||||
if let Some(info) = json.get("info_list").and_then(|list| list.get(i)) {
|
||||
data.push(info.clone());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
continue; // Skip the rest of the loop for this entry
|
||||
}
|
||||
|
||||
|
||||
|
||||
data.push(json);
|
||||
//println!("Parsed JSON: {:?}", json);
|
||||
// let mut data_entry = SpectralInfo::new();
|
||||
// data_entry.sensor_id = json.get("SensorId").and_then(Value::as_str).unwrap_or_default().to_string();
|
||||
// data_entry.wave_coeff[0]=json["WaveCoeff"]["a1"].as_f64().unwrap_or(0.0);
|
||||
// data_entry.wave_coeff[1]=json["WaveCoeff"]["a2"].as_f64().unwrap_or(0.0);
|
||||
// data_entry.wave_coeff[2]=json["WaveCoeff"]["a3"].as_f64().unwrap_or(0.0);
|
||||
// data_entry.wave_coeff[3]=json["WaveCoeff"]["a4"].as_f64().unwrap_or(0.0);
|
||||
// data.push(data_entry);
|
||||
// Parse JSON string
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
iris_data.spectral_info_section = data;
|
||||
},
|
||||
0xF0F0F0F0 => { // Other info section
|
||||
if section_length == 0 {
|
||||
iris_data.other_info_section = Vec::new(); // Handle empty section
|
||||
continue; // Skip empty section
|
||||
}
|
||||
let count = read_section_count(&mut reader)?;
|
||||
let mut data = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
let mut tempbuffer = [0u8; 3]; // Adjust size as needed
|
||||
reader.read_exact(&mut tempbuffer)?;
|
||||
let lenth = u16::from_le_bytes([tempbuffer[0], tempbuffer[1]]) as usize;
|
||||
let info_type = u8::from_le_bytes([tempbuffer[2]]);
|
||||
let mut tempvector = vec![0u8; lenth];
|
||||
reader.read_exact(&mut tempvector)?;
|
||||
// Convert to String
|
||||
let json_string = String::from_utf8(tempvector).unwrap_or_default();
|
||||
let json_string = json_string.trim_end_matches('\0').to_string();
|
||||
//print!("JSON String: {}", json_string);
|
||||
let json: Value = match serde_json::from_str(&json_string) {
|
||||
Ok(json) => json,
|
||||
Err(e) => {
|
||||
eprintln!("Error parsing JSON: {}", e);
|
||||
continue; // Skip this entry if parsing fails
|
||||
}
|
||||
}; // Handle parsing error gracefully
|
||||
data.push(json);
|
||||
|
||||
}
|
||||
iris_data.other_info_section = data;
|
||||
},
|
||||
0x0F0F0F0F => { // Image info section
|
||||
if section_length== 0 {
|
||||
iris_data.image_info_section= Vec::new(); // Handle empty section
|
||||
continue; // Skip empty section
|
||||
|
||||
}
|
||||
let count = read_section_count(&mut reader)?;
|
||||
let mut data = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
data.push(read_image_info(&mut reader)?);
|
||||
}
|
||||
iris_data.image_info_section = data;
|
||||
},
|
||||
_ => {
|
||||
// Skip unknown sections
|
||||
let mut buf = vec![0u8; section_length as usize];
|
||||
reader.read_exact(&mut buf)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(iris_data)
|
||||
}
|
||||
|
||||
fn read_section_count<R: Read>(reader: &mut R) -> Result<usize> {
|
||||
let mut count_buf = [0u8; 2];
|
||||
reader.read_exact(&mut count_buf)?;
|
||||
Ok(u16::from_le_bytes(count_buf) as usize)
|
||||
}
|
||||
|
||||
// pub fn read_other_info<R: Read>(reader: &mut R) -> Result<OtherInfo> {
|
||||
// let mut info = OtherInfo::new();
|
||||
|
||||
// // Read info type
|
||||
// let mut type_buf = [0u8; 1];
|
||||
// reader.read_exact(&mut type_buf)?;
|
||||
// info.info_type = type_buf[0];
|
||||
|
||||
// // Read data length
|
||||
// let mut len_buf = [0u8; 8];
|
||||
// reader.read_exact(&mut len_buf)?;
|
||||
// let data_len = u64::from_le_bytes(len_buf) as usize;
|
||||
|
||||
// // Read data
|
||||
// info.data.resize(data_len, 0);
|
||||
// reader.read_exact(&mut info.data)?;
|
||||
|
||||
// Ok(info)
|
||||
// }
|
||||
fn remove_after_null_split_once(s: String) -> String {
|
||||
if let Some((before_null, _after_null)) = s.split_once('\0') {
|
||||
// 返回 \0 之前的部分
|
||||
before_null.to_string()
|
||||
} else {
|
||||
// 如果没有找到 \0,就返回原始 String
|
||||
s
|
||||
}
|
||||
}
|
||||
pub fn read_spectral_data<R: Read>(reader: &mut R) -> Result<SpectralData> {
|
||||
let mut data = SpectralData::new();
|
||||
|
||||
// Read fixed-size fields
|
||||
let mut name_buf = [0u8; 100];
|
||||
|
||||
reader.read_exact(&mut name_buf)?;
|
||||
name_buf[99] = 0; // Ensure null termination
|
||||
let temp= String::from_utf8_lossy(&name_buf);
|
||||
data.name = temp.trim_end_matches('\0').to_string();
|
||||
data.name = remove_after_null_split_once(data.name);
|
||||
|
||||
let mut sensor_buf = [0u8; 50];
|
||||
reader.read_exact(&mut sensor_buf)?;
|
||||
data.sensor_id = String::from_utf8_lossy(&sensor_buf).trim_end_matches('\0').to_string();
|
||||
data.sensor_id = remove_after_null_split_once(data.sensor_id);
|
||||
let mut uint8_buf = [0u8; 1];
|
||||
|
||||
reader.read_exact(&mut uint8_buf)?;
|
||||
data.fiber_id = uint8_buf[0];
|
||||
|
||||
|
||||
data.collection_time = read_time(reader)?;
|
||||
|
||||
|
||||
let mut float_buf = [0u8; 8];
|
||||
reader.read_exact(&mut float_buf)?;
|
||||
data.exposure = f64::from_le_bytes(float_buf);
|
||||
|
||||
let mut float_buf = [0u8; 4];
|
||||
reader.read_exact(&mut float_buf)?;
|
||||
data.gain = f32::from_le_bytes(float_buf);
|
||||
|
||||
let mut byte_buf = [0u8; 1];
|
||||
reader.read_exact(&mut byte_buf)?;
|
||||
data.data_type = byte_buf[0];
|
||||
|
||||
reader.read_exact(&mut byte_buf)?;
|
||||
data.pixel_size = byte_buf[0];
|
||||
|
||||
reader.read_exact(&mut byte_buf)?;
|
||||
data.ground_type = byte_buf[0];
|
||||
|
||||
let mut short_buf = [0u8; 2];
|
||||
reader.read_exact(&mut short_buf)?;
|
||||
data.bands = u16::from_le_bytes(short_buf);
|
||||
|
||||
reader.read_exact(&mut byte_buf)?;
|
||||
data.valid_flag = byte_buf[0];
|
||||
let data_len=data.pixel_size as usize * data.bands as usize;
|
||||
// Read the length of the spectral_data vector
|
||||
// let mut len_buf = [0u8; 8];
|
||||
// reader.read_exact(&mut len_buf)?;
|
||||
// let data_len = u64::from_le_bytes(len_buf) as usize;
|
||||
|
||||
// Read the spectral_data vector
|
||||
data.spectral_data.resize(data_len, 0);
|
||||
reader.read_exact(&mut data.spectral_data)?;
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
411
src-tauri/src/myformatiris/structures.rs
Normal file
@ -0,0 +1,411 @@
|
||||
|
||||
pub const DATA_TYPE_UINT8: u8 = 0x10;
|
||||
pub const DATA_TYPE_INT16: u8 = 0x11;
|
||||
pub const DATA_TYPE_UINT16: u8 = 0x12;
|
||||
pub const DATA_TYPE_INT32: u8 = 0x13;
|
||||
pub const DATA_TYPE_UINT32: u8 = 0x14;
|
||||
pub const DATA_TYPE_FLOAT32: u8 = 0x20;
|
||||
pub const DATA_TYPE_FLOAT64: u8 = 0x21;
|
||||
|
||||
/* 0 dn 1 rad 2 ref 3 irad 4 califile 5 flat_ref 6 dark_dn 7 flat_dn */
|
||||
|
||||
pub const Target_Spectral_Type_DN:u8 = 0x00;
|
||||
pub const Target_Spectral_Type_Rad:u8 = 0x01;
|
||||
pub const Target_Spectral_Type_Ref:u8 = 0x02;
|
||||
pub const Target_Spectral_Type_IRad:u8 = 0x03;
|
||||
pub const Target_Spectral_Type_CaliFile_Gain:u8 = 0x04;
|
||||
pub const Target_Spectral_Type_FlatRef:u8 = 0x05;
|
||||
pub const Target_Spectral_Type_DarkDN:u8 = 0x06;
|
||||
pub const Target_Spectral_Type_FlatDN:u8 = 0x07;
|
||||
pub const Target_LAMP_VALUE_SCALED:u8 = 0x08;
|
||||
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
|
||||
|
||||
|
||||
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
|
||||
pub struct TimeStruct {
|
||||
pub time_zone: i8,
|
||||
pub year: u16,
|
||||
pub month: u8,
|
||||
pub day: u8,
|
||||
pub hour: u8,
|
||||
pub minute: u8,
|
||||
pub second: u8,
|
||||
pub millisecond: u16,
|
||||
}
|
||||
|
||||
impl TimeStruct {
|
||||
pub fn new() -> Self {
|
||||
TimeStruct {
|
||||
time_zone: 0,
|
||||
year: 0,
|
||||
month: 1,
|
||||
day: 1,
|
||||
hour: 0,
|
||||
minute: 0,
|
||||
second: 0,
|
||||
millisecond: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
|
||||
pub struct SpectralData {
|
||||
pub name: String,
|
||||
pub sensor_id: String,
|
||||
pub fiber_id: u8,
|
||||
pub collection_time: TimeStruct,
|
||||
pub exposure: f64,
|
||||
pub gain: f32,
|
||||
pub data_type: u8,
|
||||
pub pixel_size: u8,
|
||||
pub ground_type: u8,
|
||||
pub bands: u16,
|
||||
pub valid_flag: u8,
|
||||
pub spectral_data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl SpectralData {
|
||||
pub fn new() -> Self {
|
||||
SpectralData {
|
||||
name: String::new(),
|
||||
sensor_id: String::new(),
|
||||
fiber_id:0,
|
||||
collection_time: TimeStruct::new(),
|
||||
exposure: 0.0,
|
||||
gain: 0.0,
|
||||
data_type: 0,
|
||||
pixel_size: 0,
|
||||
ground_type: 0,
|
||||
bands: 0,
|
||||
valid_flag: 0,
|
||||
spectral_data: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Get_Spectral_Data(&self)-> Vec<f64> {
|
||||
let mut retrun_data: Vec<f64> = Vec::new();
|
||||
let datatype = self.data_type;
|
||||
let bands = self.bands as usize;
|
||||
match datatype {
|
||||
DATA_TYPE_UINT8 => {
|
||||
// uint8
|
||||
for i in 0..bands {
|
||||
retrun_data.push(self.spectral_data[i] as f64);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
DATA_TYPE_INT16 => {
|
||||
// int16
|
||||
self.spectral_data.chunks(2).for_each(|chunk| {
|
||||
if chunk.len() == 2 {
|
||||
let value = i16::from_le_bytes([chunk[0], chunk[1]]);
|
||||
retrun_data.push(value as f64);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
DATA_TYPE_UINT16 => {
|
||||
// uint16
|
||||
self.spectral_data.chunks(2).for_each(|chunk| {
|
||||
if chunk.len() == 2 {
|
||||
let value = u16::from_le_bytes([chunk[0], chunk[1]]);
|
||||
retrun_data.push(value as f64);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
DATA_TYPE_INT32 => {
|
||||
// int32
|
||||
|
||||
|
||||
self.spectral_data.chunks(4).for_each(|chunk| {
|
||||
if chunk.len() == 4 {
|
||||
let value = i32::from_le_bytes([
|
||||
chunk[0],
|
||||
chunk[1],
|
||||
chunk[2],
|
||||
chunk[3],
|
||||
]);
|
||||
retrun_data.push(value as f64);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
DATA_TYPE_UINT32 => {
|
||||
// uint32
|
||||
for i in (0..self.spectral_data.len()).step_by(4) {
|
||||
let value = u32::from_le_bytes([
|
||||
self.spectral_data[i],
|
||||
self.spectral_data[i + 1],
|
||||
self.spectral_data[i + 2],
|
||||
self.spectral_data[i + 3],
|
||||
]);
|
||||
retrun_data.push(value as f64);
|
||||
}
|
||||
}
|
||||
DATA_TYPE_FLOAT32 => {
|
||||
// float32
|
||||
for i in (0..self.spectral_data.len()).step_by(4) {
|
||||
let value = f32::from_le_bytes([
|
||||
self.spectral_data[i],
|
||||
self.spectral_data[i + 1],
|
||||
self.spectral_data[i + 2],
|
||||
self.spectral_data[i + 3],
|
||||
]);
|
||||
retrun_data.push(value as f64);
|
||||
}
|
||||
}
|
||||
DATA_TYPE_FLOAT64 => {
|
||||
// float64
|
||||
for i in (0..self.spectral_data.len()).step_by(8) {
|
||||
let value = f64::from_le_bytes([
|
||||
self.spectral_data[i],
|
||||
self.spectral_data[i + 1],
|
||||
self.spectral_data[i + 2],
|
||||
self.spectral_data[i + 3],
|
||||
self.spectral_data[i + 4],
|
||||
self.spectral_data[i + 5],
|
||||
self.spectral_data[i + 6],
|
||||
self.spectral_data[i + 7],
|
||||
]);
|
||||
retrun_data.push(value);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Unsupported data type
|
||||
panic!("Unsupported data type: {}", datatype);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
retrun_data
|
||||
|
||||
|
||||
}
|
||||
pub fn Set_Spectral_Data(&mut self, data: Vec<f64>,datatype: u8) {
|
||||
self.data_type = datatype;
|
||||
self.bands = data.len() as u16;
|
||||
self.spectral_data.clear();
|
||||
|
||||
// let datatype = self.data_type;
|
||||
let bands = self.bands as usize;
|
||||
match datatype {
|
||||
DATA_TYPE_UINT8 => {
|
||||
// uint8
|
||||
self.pixel_size = 1;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
self.spectral_data.push(data[i] as u8);
|
||||
} else {
|
||||
self.spectral_data.push(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
DATA_TYPE_INT16 => {
|
||||
// int16
|
||||
self.pixel_size = 2;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
let value = data[i] as i16;
|
||||
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
||||
} else {
|
||||
self.spectral_data.extend_from_slice(&[0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
DATA_TYPE_UINT16 => {
|
||||
// uint16
|
||||
self.pixel_size = 2;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
let value = data[i] as u16;
|
||||
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
||||
} else {
|
||||
self.spectral_data.extend_from_slice(&[0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
DATA_TYPE_INT32 => {
|
||||
// int32
|
||||
self.pixel_size = 4;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
let value = data[i] as i32;
|
||||
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
||||
} else {
|
||||
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
DATA_TYPE_UINT32 => {
|
||||
// uint32
|
||||
self.pixel_size = 4;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
let value = data[i] as u32;
|
||||
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
||||
} else {
|
||||
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
DATA_TYPE_FLOAT32 => {
|
||||
// float32
|
||||
self.pixel_size = 4;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
let value = data[i] as f32;
|
||||
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
||||
} else {
|
||||
self.spectral_data.extend_from_slice(&[0, 0, 0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
DATA_TYPE_FLOAT64 => {
|
||||
// float64
|
||||
self.pixel_size = 8;
|
||||
self.spectral_data.clear();
|
||||
for i in 0..bands {
|
||||
if i < data.len() {
|
||||
let value = data[i];
|
||||
self.spectral_data.extend_from_slice(&value.to_le_bytes());
|
||||
} else {
|
||||
self.spectral_data.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Unsupported data type
|
||||
panic!("Unsupported data type: {}", datatype);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Debug, Clone, PartialEq)]
|
||||
// pub struct OtherInfo {
|
||||
// pub info_type: u8,
|
||||
// pub data: Vec<u8>, // Assuming the data is variable length
|
||||
// }
|
||||
|
||||
// impl OtherInfo {
|
||||
// pub fn new() -> Self {
|
||||
// OtherInfo {
|
||||
// info_type: 0,
|
||||
// data: Vec::new(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
#[derive(serde::Serialize, Debug, Clone, PartialEq)]
|
||||
pub struct OneIRISData {
|
||||
pub spectral_data_section: Vec<SpectralData>,
|
||||
pub spectral_info_section: Vec<serde_json::Value>, // Using serde_json::Value for flexibility
|
||||
pub other_info_section: Vec<serde_json::Value>,
|
||||
pub image_info_section: Vec<ImageInfo>,
|
||||
}
|
||||
|
||||
impl OneIRISData {
|
||||
pub fn new() -> Self {
|
||||
OneIRISData {
|
||||
spectral_data_section: Vec::new(),
|
||||
spectral_info_section: Vec::new(),
|
||||
other_info_section: Vec::new(),
|
||||
image_info_section: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Debug, Clone, PartialEq)]
|
||||
// pub struct SpectralInfo {
|
||||
// pub sensor_id: String,
|
||||
// pub wave_coeff: [f64; 4],
|
||||
|
||||
// }
|
||||
|
||||
// impl SpectralInfo {
|
||||
// pub fn new() -> Self {
|
||||
// SpectralInfo {
|
||||
// sensor_id: String::new(),
|
||||
// wave_coeff: [0.0; 4],
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[derive(serde::Serialize,Debug, Clone, PartialEq)]
|
||||
pub struct ImageInfo {
|
||||
pub data_length: u64,
|
||||
pub name: String,
|
||||
pub collection_time: TimeStruct,
|
||||
pub info_type: u8,
|
||||
pub image_data: Vec<u8>, // Assuming the data is variable length
|
||||
}
|
||||
|
||||
impl ImageInfo {
|
||||
pub fn new() -> Self {
|
||||
ImageInfo {
|
||||
data_length: 0,
|
||||
name: String::new(),
|
||||
collection_time: TimeStruct::new(),
|
||||
info_type: 0,
|
||||
image_data: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_time_struct() {
|
||||
let time = TimeStruct::new();
|
||||
assert_eq!(time.time_zone, 0);
|
||||
assert_eq!(time.year, 0);
|
||||
assert_eq!(time.month, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_spectral_data() {
|
||||
let data = SpectralData::new();
|
||||
assert_eq!(data.name, "");
|
||||
assert_eq!(data.bands, 0);
|
||||
assert!(data.spectral_data.is_empty());
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_spectral_info() {
|
||||
// let info = SpectralInfo::new();
|
||||
// assert_eq!(info.sensor_id, "");
|
||||
// assert_eq!(info.wave_coeff, [0.0; 4]);
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn test_other_info() {
|
||||
// let info = OtherInfo::new();
|
||||
// assert_eq!(info.info_type, 0);
|
||||
// assert!(info.data.is_empty());
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn test_image_info() {
|
||||
let info = ImageInfo::new();
|
||||
assert_eq!(info.data_length, 0);
|
||||
assert_eq!(info.name, "");
|
||||
assert!(info.image_data.is_empty());
|
||||
}
|
||||
}
|
||||
222
src-tauri/src/myformatiris/write.rs
Normal file
@ -0,0 +1,222 @@
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write, Result};
|
||||
use std::vec;
|
||||
use serde_json::json;
|
||||
|
||||
// use crate::write;
|
||||
|
||||
use super::structures::{TimeStruct, SpectralData, ImageInfo,OneIRISData};
|
||||
|
||||
// Internal writer functions remain the same
|
||||
fn write_time<W: Write>(time: &TimeStruct, writer: &mut W) -> Result<()> {
|
||||
writer.write_all(&[time.time_zone as u8])?;
|
||||
writer.write_all(&time.year.to_le_bytes())?;
|
||||
writer.write_all(&[time.month])?;
|
||||
writer.write_all(&[time.day])?;
|
||||
writer.write_all(&[time.hour])?;
|
||||
writer.write_all(&[time.minute])?;
|
||||
writer.write_all(&[time.second])?;
|
||||
writer.write_all(&time.millisecond.to_le_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn write_image_info<W: Write>(info: &ImageInfo, writer: &mut W) -> Result<()> {
|
||||
// Write data length
|
||||
writer.write_all(&info.data_length.to_le_bytes())?;
|
||||
|
||||
// Write name (fixed size 100 bytes)
|
||||
let mut name_buf = [0u8; 100];
|
||||
let name_bytes = info.name.as_bytes();
|
||||
name_buf[..info.name.len().min(99)].copy_from_slice(name_bytes[0..name_bytes.len().min(99)].as_ref());
|
||||
writer.write_all(&name_buf)?;
|
||||
|
||||
// Write collection time
|
||||
write_time(&info.collection_time, writer)?;
|
||||
|
||||
// Write info type
|
||||
writer.write_all(&[info.info_type])?;
|
||||
|
||||
// Write image data
|
||||
writer.write_all(&info.image_data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn write_spectral_data<W: Write>(data: &SpectralData, writer: &mut W) -> Result<()> {
|
||||
// Write fixed-size fields
|
||||
let mut name_buf = [0u8; 100];
|
||||
|
||||
let namebyte= data.name.as_bytes();
|
||||
name_buf[..data.name.len().min(99)].copy_from_slice(namebyte[0..namebyte.len().min(99)].as_ref());
|
||||
writer.write_all(&name_buf)?;
|
||||
|
||||
let mut sensor_buf = [0u8; 50];
|
||||
let sensor_id_bytes = data.sensor_id.as_bytes();
|
||||
sensor_buf[..data.sensor_id.len().min(49)].copy_from_slice(sensor_id_bytes[0..sensor_id_bytes.len().min(49)].as_ref());
|
||||
writer.write_all(&sensor_buf)?;
|
||||
writer.write_all(&[data.fiber_id])?;
|
||||
|
||||
write_time(&data.collection_time, writer)?;
|
||||
writer.write_all(&data.exposure.to_le_bytes())?;
|
||||
writer.write_all(&data.gain.to_le_bytes())?;
|
||||
writer.write_all(&[data.data_type])?;
|
||||
writer.write_all(&[data.pixel_size])?;
|
||||
writer.write_all(&[data.ground_type])?;
|
||||
writer.write_all(&data.bands.to_le_bytes())?;
|
||||
writer.write_all(&[data.valid_flag])?;
|
||||
|
||||
// // Write the length of the spectral_data vector
|
||||
// writer.write_all(&(data.spectral_data.len() as u64).to_le_bytes())?;
|
||||
// Write the spectral_data vector
|
||||
writer.write_all(&data.spectral_data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn caculate_spectral_data_length(data: &Vec<SpectralData>) -> u64 {
|
||||
let mut lenth:u64 = 0;
|
||||
//加上u16的长度
|
||||
lenth += 2; // bands
|
||||
//加上u8的长度
|
||||
// let numberofspectral=data.len();
|
||||
for datatemp in data {
|
||||
lenth += 100; // name
|
||||
lenth += 50; // sensor_id
|
||||
lenth += 1 ; // fiber_id
|
||||
lenth += 10; // time_zone
|
||||
lenth += 8; // exposure
|
||||
lenth += 4; // gain
|
||||
lenth += 1; // data_type
|
||||
lenth += 1; // pixel_size
|
||||
lenth += 1; // ground_type
|
||||
lenth += 2; // bands
|
||||
lenth += 1; // valid_flag
|
||||
lenth += datatemp.spectral_data.len() as u64;
|
||||
|
||||
}
|
||||
lenth
|
||||
|
||||
}
|
||||
pub fn caculate_image_info_length(data: &Vec<ImageInfo>) -> u64 {
|
||||
let mut lenth: u64 = 0;
|
||||
if data.is_empty() {
|
||||
return lenth;
|
||||
}
|
||||
lenth +=2;
|
||||
for info in data {
|
||||
lenth += 8; // data_length
|
||||
lenth += 100; // name
|
||||
lenth += 10; // time_zone
|
||||
lenth += 1; // info_type
|
||||
lenth += info.image_data.len() as u64; // image_data length
|
||||
}
|
||||
lenth
|
||||
}
|
||||
|
||||
|
||||
pub fn cacluate_other_info_length(data: &Vec<serde_json::Value>) -> (Vec<u8>, u64) {
|
||||
let mut lenth: u64 = 0;
|
||||
let mut vecback= Vec::new();
|
||||
if data.is_empty() {
|
||||
return (vecback, lenth);
|
||||
}
|
||||
// for info in data {
|
||||
// lenth+=1; // info_type
|
||||
// lenth+=8; // data length
|
||||
// lenth += info.data.len() as u64; // data length
|
||||
// vecback.push(info.info_type);
|
||||
// vecback.extend_from_slice(&(info.data.len() as u64).to_le_bytes());
|
||||
// vecback.extend_from_slice(&info.data);
|
||||
// }
|
||||
(vecback, lenth)
|
||||
}
|
||||
|
||||
pub fn caculate_spectral_info_length(data: &Vec<serde_json::Value>) -> (Vec<u8>, u64) {
|
||||
let mut lenth: u64 = 0;
|
||||
let mut vecback= Vec::new();
|
||||
if data.is_empty() {
|
||||
return (vecback, lenth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
lenth+=2; // sensor_id
|
||||
let lenthofinfo=data.len() as u16;
|
||||
vecback.extend_from_slice(&lenthofinfo.to_le_bytes()); // Number of spectral info entries
|
||||
|
||||
|
||||
for info in data {
|
||||
lenth+=2;
|
||||
lenth+=1;
|
||||
let mut lenthofthisinfo:u16=0;
|
||||
let json=info;
|
||||
let json_string = serde_json::to_string(&json).unwrap();
|
||||
let json_bytes = json_string.as_bytes();
|
||||
lenthofthisinfo= json_bytes.len() as u16+1;
|
||||
lenth += lenthofthisinfo as u64 ;
|
||||
|
||||
// 将长度转换为字节并添加到 vecback
|
||||
vecback.extend_from_slice(&lenthofthisinfo.to_le_bytes());
|
||||
vecback.push(0x00); // json 标识
|
||||
vecback.extend_from_slice(json_bytes);
|
||||
vecback.push(0x00); // 添加一个字节的0x00
|
||||
}
|
||||
(vecback, lenth)
|
||||
|
||||
}
|
||||
pub fn wirte_iris_data(data:&OneIRISData,filepath:&str) -> Result<()> {
|
||||
let mut file = File::create(filepath)?;
|
||||
//写入光谱数据header
|
||||
let SPectralData_Flag:u32=0x00FF00FF;
|
||||
file.write_all(&SPectralData_Flag.to_le_bytes())?;
|
||||
let mut sectionlenth: u64 = caculate_spectral_data_length(&data.spectral_data_section);
|
||||
file.write_all(&(sectionlenth).to_le_bytes())?; // Section length
|
||||
let numberofspectral=data.spectral_data_section.len() as u16;
|
||||
file.write_all(&numberofspectral.to_le_bytes())?; // Number of spectral data entries
|
||||
// Write spectral data section
|
||||
for spectral_data in &data.spectral_data_section {
|
||||
write_spectral_data(spectral_data, &mut file)?;
|
||||
}
|
||||
|
||||
// Write section length
|
||||
|
||||
// Write spectral info section
|
||||
let spectral_info_flag: u32 = 0xFF00FF00;
|
||||
|
||||
|
||||
let (spectral_info_vec, spectral_info_length) = caculate_spectral_info_length(&data.spectral_info_section);
|
||||
file.write_all(&spectral_info_flag.to_le_bytes())?; // Spectral info 区块标识
|
||||
file.write_all(&spectral_info_length.to_le_bytes())?; // Section length
|
||||
if spectral_info_length != 0 {
|
||||
file.write_all(&spectral_info_vec)?; // Write the spectral info section data
|
||||
|
||||
}
|
||||
|
||||
let other_info_flag: u32 = 0xF0F0F0F0;
|
||||
let (other_info_vec, other_info_length) = cacluate_other_info_length(&data.other_info_section);
|
||||
file.write_all(&other_info_flag.to_le_bytes())?; // Other info 区块标识
|
||||
file.write_all(&other_info_length.to_le_bytes())?; // Section length
|
||||
if other_info_length != 0 {
|
||||
file.write_all(&other_info_vec)?; // Write the other info section data
|
||||
}
|
||||
|
||||
|
||||
|
||||
let image_info_flag: u32 = 0x0F0F0F0F;
|
||||
file.write_all(&image_info_flag.to_le_bytes())?; // Image info 区块标识
|
||||
let image_info_length = caculate_image_info_length(&data.image_info_section);
|
||||
file.write_all(&image_info_length.to_le_bytes())?; // Section length
|
||||
if image_info_length != 0 {
|
||||
let numberofimageinfo = data.image_info_section.len() as u16;
|
||||
file.write_all(&numberofimageinfo.to_le_bytes())?; // Write the image info section data
|
||||
// Write image info section
|
||||
for image_info in &data.image_info_section {
|
||||
write_image_info(image_info, &mut file)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1,12 +1,11 @@
|
||||
use tklog::{
|
||||
debugs, errors, fatals, infos,
|
||||
sync::Logger,LEVEL, LOG,
|
||||
traces, warns, Format, MODE,async_traces,
|
||||
infos,
|
||||
sync::Logger, Format, MODE,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
// fmt::format,
|
||||
borrow::{ BorrowMut}, sync::{Arc, Mutex}, thread::sleep
|
||||
borrow::{ BorrowMut}, sync::{Arc, Mutex}
|
||||
};
|
||||
|
||||
struct LOGERME{
|
||||
@ -31,11 +30,11 @@ lazy_static! {
|
||||
|
||||
pub fn change_log_path(path: &str,string: &str) {
|
||||
if string=="RUST"{
|
||||
let mut loggerglobel = LOGERGLOBLE.lock().unwrap();
|
||||
let loggerglobel = LOGERGLOBLE.lock().unwrap();
|
||||
let mut log=loggerglobel.logger_rust.lock().unwrap();
|
||||
log.set_cutmode_by_time(path, MODE::DAY, 10, false);
|
||||
}else if string=="JS"{
|
||||
let mut loggerglobel=LOGERGLOBLE.lock().unwrap();
|
||||
let loggerglobel=LOGERGLOBLE.lock().unwrap();
|
||||
let mut log=loggerglobel.logger_js.lock().unwrap();
|
||||
log.set_cutmode_by_time(path, MODE::DAY, 10, false);
|
||||
}
|
||||
@ -44,7 +43,7 @@ pub fn change_log_path(path: &str,string: &str) {
|
||||
pub fn initlog() {
|
||||
|
||||
//let mut logger = LOGERGloble.lock().unwrap().LOGGER_RUST;
|
||||
let mut loggerglobel = LOGERGLOBLE.lock().unwrap();
|
||||
let loggerglobel = LOGERGLOBLE.lock().unwrap();
|
||||
let mut log=loggerglobel.logger_rust.lock().unwrap();
|
||||
log.set_console(true).set_format(Format::Date|Format::Time).set_formatter("{time} {file}{level}:{message}\n")
|
||||
.set_cutmode_by_time("rust_log.log",MODE::DAY, 10, false);
|
||||
@ -59,7 +58,7 @@ pub fn initlog() {
|
||||
pub fn logtorust<T>(str:T)
|
||||
where T: std::fmt::Display
|
||||
{
|
||||
let mut loggerglobe=LOGERGLOBLE.lock().unwrap();
|
||||
let loggerglobe=LOGERGLOBLE.lock().unwrap();
|
||||
let mut log=Arc::clone(&loggerglobe.logger_rust);
|
||||
|
||||
let log1 = log.borrow_mut();
|
||||
@ -69,7 +68,7 @@ where T: std::fmt::Display
|
||||
pub fn logtojs<T>(str:T)
|
||||
where T: std::fmt::Display
|
||||
{
|
||||
let mut loggerglobe=LOGERGLOBLE.lock().unwrap();
|
||||
let loggerglobe=LOGERGLOBLE.lock().unwrap();
|
||||
let mut log=Arc::clone(&loggerglobe.logger_js);
|
||||
|
||||
let log1 = log.borrow_mut();
|
||||
|
||||
@ -103,11 +103,12 @@ pub fn sendtoprot(data: Vec<u8>) -> String {
|
||||
if port_info.port_name == "NON" {
|
||||
return format!("Port is not set");
|
||||
}
|
||||
|
||||
println!("{:?}", data.iter().map(|&byte| format!("{:02X}", byte)).collect::<Vec<String>>().join(" "));
|
||||
match &mut port_info.port {
|
||||
Some(p) => match p.write(&data) {
|
||||
Ok(_) => {
|
||||
println!("Data sent");
|
||||
|
||||
return String::from("Data sent");
|
||||
}
|
||||
Err(e) => {
|
||||
@ -130,7 +131,7 @@ pub fn clearserilport() -> String{
|
||||
match &mut port_info.port {
|
||||
Some(p) => {
|
||||
p.set_timeout(Duration::from_millis(100)).unwrap();
|
||||
while true{
|
||||
loop{
|
||||
let sizeread =match p.read(&mut buf){
|
||||
Ok(size)=>{size},
|
||||
Err(_e)=>{return "Port is not open".to_string()}
|
||||
@ -245,10 +246,10 @@ pub fn readforport()->Vec<u8>{
|
||||
if port_info.port_name == "NON" {
|
||||
return "Port is not set".as_bytes().to_vec();
|
||||
}
|
||||
let mut buf: Vec<u8> = vec![0; 1000];
|
||||
let mut buf: Vec<u8> = vec![0; 5000];
|
||||
match &mut port_info.port {
|
||||
Some(p) => {
|
||||
p.set_timeout(Duration::from_millis(100)).unwrap();
|
||||
p.set_timeout(Duration::from_millis(10)).unwrap();
|
||||
let sizeread =match p.read(&mut buf){
|
||||
Ok(size)=>{size},
|
||||
Err(_e)=>{0}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
"package": {
|
||||
"productName": "SpectralPlot",
|
||||
"version": "0.5.57"
|
||||
"version": "0.6.81"
|
||||
},
|
||||
"tauri": {
|
||||
|
||||
@ -59,7 +59,11 @@
|
||||
"targets": "all",
|
||||
"identifier": "lele.rlx",
|
||||
"resources": [
|
||||
"config.json","is11lib.dll"
|
||||
"config.json","is11lib.dll" , "iris_is3lib.dll",
|
||||
"msvcp140.dll",
|
||||
"vcruntime140.dll",
|
||||
"vcruntime140_1.dll",
|
||||
"ucrtbase.dll"
|
||||
],
|
||||
"windows": {
|
||||
|
||||
|
||||
BIN
src-tauri/ucrtbase.dll
Normal file
21
src-tauri/updatelog.md
Normal file
@ -0,0 +1,21 @@
|
||||
# IRIS SpectralPlot 更新日志
|
||||
|
||||
---
|
||||
|
||||
## 公司信息
|
||||
|
||||
* **公司名称**:北京依锐思遥感技术有限公司
|
||||
* **官方网站**:[http://www.iris-rs.cn](http://www.iris-rs.cn)
|
||||
* **联系邮箱**:renlixin@iris-rs.cn
|
||||
|
||||
---
|
||||
|
||||
## 更新日志
|
||||
|
||||
* **v0.6.58** 增加了IS3的支持。
|
||||
* **v0.6.59** 将连续保存功能分割为“连续(不保存)”和“连续保存”两个独立功能。
|
||||
* **v0.6.60** 增加了IS3快门的控制功能。
|
||||
* **v0.6.62** 修正了保存逻辑,并修复了波长倒置的问题。
|
||||
* **v0.6.65** 增加了HH3定标功能。
|
||||
* **v0.6.66** 增加了HH3波长定标所需的波长参数,并将寻峰最小值调整为3000。
|
||||
* **v0.6.81** 解决了is3控制时偶尔会卡顿的问题
|
||||
BIN
src-tauri/vcruntime140.dll
Normal file
BIN
src-tauri/vcruntime140_1.dll
Normal file
55
src/App.vue
@ -1,26 +1,47 @@
|
||||
<script setup>
|
||||
// This starter template is using Vue 3 <script setup> SFCs
|
||||
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
|
||||
<script>
|
||||
import Greet from "./components/Greet.vue";
|
||||
|
||||
import AppHyperSpectral from "./AppHyperSpectral.vue";
|
||||
import APPDataview from "./DataView/APPDataview.vue";
|
||||
import EventBus from "./eventBus.js";
|
||||
export default {
|
||||
components: {
|
||||
Greet,
|
||||
AppHyperSpectral,
|
||||
APPDataview
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentView: 'AppHyperSpectral', // 当前显示的视图
|
||||
viewList: ['AppHyperSpectral', 'APPDataview'],
|
||||
indexofcomponent: 0,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
EventBus.on('changemainvue', this.onchangemainvue);
|
||||
console.log(window.__TAURI__);
|
||||
},
|
||||
methods: {
|
||||
onchangemainvue(){
|
||||
// 切换到下一个视图
|
||||
this.indexofcomponent++;
|
||||
if (this.indexofcomponent >= this.viewList.length) {
|
||||
this.indexofcomponent = 0;
|
||||
}
|
||||
this.currentView = this.viewList[this.indexofcomponent];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
|
||||
|
||||
<Greet />
|
||||
</div>
|
||||
<keep-alive>
|
||||
<component
|
||||
:is="currentView"
|
||||
style="user-select: none; width: 100vw; height: 100vh;"
|
||||
/>
|
||||
</keep-alive>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo.vite:hover {
|
||||
filter: drop-shadow(0 0 2em #747bff);
|
||||
}
|
||||
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #249b73);
|
||||
/* Your additional CSS code here */
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -119,6 +119,7 @@ export default {
|
||||
|
||||
<template>
|
||||
|
||||
|
||||
<BToastOrchestrator />
|
||||
|
||||
|
||||
|
||||
216
src/DataView/APPDataview.vue
Normal file
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<a-layout style="height: 100vh; width: 100vw;">
|
||||
<a-layout-header>
|
||||
<menubardatavue></menubardatavue>
|
||||
</a-layout-header>
|
||||
<a-layout>
|
||||
<a-layout-sider :resize-directions="['right']" style=" min-width: 20vw;max-width: 50vw;">
|
||||
<a-dropdown trigger="contextMenu" alignPoint :style="{ display: 'block' }">
|
||||
<GuiLeftSider class="lefttree" v-on:NodeClicked="ononeFilechoese"
|
||||
v-on:NodeDblClicked="onFileDblClick" v-on:FilesSelected="onFilesSelected"
|
||||
v-on:FolderClicked="onFolderClicked" v-on:FolderDblClicked="onFolderDblClick"
|
||||
v-on:SaveFilesRequested="onSaveFilesRequested" v-on:reset="resetTreeData">
|
||||
</GuiLeftSider>
|
||||
<template #content>
|
||||
<a-doption @click="onShowCurvesClick">显示曲线</a-doption>
|
||||
<a-doption @click="openCurveSaveDialogForSelectedFiles">数据导出</a-doption>
|
||||
<!-- <a-doption>Option 3</a-doption> -->
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-layout-sider>
|
||||
<a-layout-content class="right">
|
||||
<GuiForDataShow ref="GuiForDataShow"></GuiForDataShow>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
<!-- <a-layout-footer>Footer</a-layout-footer> -->
|
||||
|
||||
<!-- 保存文件弹窗 -->
|
||||
<SaveFileDialog v-model:visible="showSaveDialog" :files="filesToSave" @save="handleSaveFiles"
|
||||
@cancel="handleCancelSave" />
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import menubardatavue from './menuvue/menubar.vue';
|
||||
import GuiForDataShow from './vuecomponents/GuiForDataShow.vue';
|
||||
import GuiLeftSider from './vuecomponents/GuiLeftSider.vue';
|
||||
import SaveFileDialog from './vuecomponents/SaveFileDialog.vue';
|
||||
import { fs } from '@tauri-apps/api';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
export default {
|
||||
name: 'APPDataview',
|
||||
components: {
|
||||
menubardatavue,
|
||||
GuiForDataShow,
|
||||
GuiLeftSider,
|
||||
SaveFileDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 初始化数据
|
||||
message: '欢迎使用 Vue!',
|
||||
selectedFilePath: null, // 存储当前选中的文件路径
|
||||
selectedFilePaths: [], // 存储多选的文件路径
|
||||
treeData: [
|
||||
{
|
||||
title: 'Trunk 0-0',
|
||||
key: '0-0',
|
||||
children: [
|
||||
{
|
||||
title: 'Branch 0-0-0',
|
||||
key: '0-0-0',
|
||||
children: [
|
||||
{
|
||||
title: 'Leaf',
|
||||
key: '0-0-0-0',
|
||||
},
|
||||
{
|
||||
title: 'Leaf',
|
||||
key: '0-0-0-1',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Branch 0-0-1',
|
||||
key: '0-0-1',
|
||||
children: [
|
||||
{
|
||||
title: 'Leaf',
|
||||
key: '0-0-1-0',
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
showSaveDialog: false,
|
||||
filesToSave: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理单个文件选择(单击)
|
||||
async ononeFilechoese(filePath) {
|
||||
// console.log('选中文件路径:', filePath);
|
||||
// 只记录选中的文件路径,不立即加载数据
|
||||
this.selectedFilePath = filePath;
|
||||
},
|
||||
|
||||
// 处理文件双击事件
|
||||
async onFileDblClick(filePath) {
|
||||
// console.log('双击文件路径:', filePath);
|
||||
// 双击时加载数据
|
||||
this.$refs.GuiForDataShow.onloaddata([filePath]);
|
||||
},
|
||||
|
||||
// 处理多个文件选择(当使用Shift或Ctrl多选时)
|
||||
async onFilesSelected(filePaths) {
|
||||
// console.log('多选文件路径:', filePaths);
|
||||
// 存储多选的文件路径
|
||||
this.selectedFilePaths = filePaths;
|
||||
// 多选时,可以选择不自动加载数据,等待用户进一步操作
|
||||
if (filePaths && filePaths.length > 0) {
|
||||
this.selectedFilePath = filePaths[0];
|
||||
}
|
||||
},
|
||||
|
||||
// 处理文件夹点击事件
|
||||
async onFolderClicked(folderPath, childFilePaths) {
|
||||
// console.log('选中文件夹:', folderPath);
|
||||
// console.log('文件夹下的文件:', childFilePaths);
|
||||
// 存储文件夹下的文件路径
|
||||
this.selectedFilePaths = childFilePaths;
|
||||
},
|
||||
|
||||
// 处理文件夹双击事件
|
||||
async onFolderDblClick(folderPath, childFilePaths) {
|
||||
// console.log('双击文件夹:', folderPath);
|
||||
// console.log('文件夹下的文件:', childFilePaths);
|
||||
|
||||
// 如果文件夹下有文件,则加载所有文件
|
||||
if (childFilePaths && childFilePaths.length > 0) {
|
||||
// 将所有文件路径传递给 GuiForDataShow 组件
|
||||
this.$refs.GuiForDataShow.onloaddata(childFilePaths);
|
||||
}
|
||||
},
|
||||
|
||||
// 处理"显示曲线"菜单项点击事件
|
||||
async onShowCurvesClick() {
|
||||
// console.log('点击显示曲线菜单项');
|
||||
// 如果有多选文件,则加载所有选中的文件
|
||||
if (this.selectedFilePaths && this.selectedFilePaths.length > 0) {
|
||||
// console.log('加载多选文件:', this.selectedFilePaths);
|
||||
this.$refs.GuiForDataShow.onloaddata(this.selectedFilePaths);
|
||||
} else if (this.selectedFilePath) {
|
||||
// 如果只有单选文件,则加载单个文件
|
||||
// console.log('加载单选文件:', this.selectedFilePath);
|
||||
this.$refs.GuiForDataShow.onloaddata(this.selectedFilePath);
|
||||
}
|
||||
},
|
||||
|
||||
resetTreeData() {
|
||||
this.selectedFilePaths = []
|
||||
this.$refs.GuiForDataShow.onloaddata(this.selectedFilePaths);
|
||||
},
|
||||
|
||||
// 处理保存文件请求
|
||||
onSaveFilesRequested(selectedFiles) {
|
||||
this.filesToSave = selectedFiles
|
||||
this.showSaveDialog = true
|
||||
},
|
||||
// 处理保存文件
|
||||
async handleSaveFiles(saveData) {
|
||||
try {
|
||||
const { files, location } = saveData
|
||||
|
||||
for (const file of files) {
|
||||
// 构建目标文件路径
|
||||
const fileName = file.label
|
||||
const targetPath = `${location}/${fileName}`
|
||||
|
||||
// 复制文件
|
||||
await fs.copyFile(file.path, targetPath)
|
||||
}
|
||||
|
||||
ElMessage.success(`成功保存 ${files.length} 个文件到 ${location}`)
|
||||
} catch (error) {
|
||||
console.error('保存文件失败:', error)
|
||||
alert('保存文件失败: ' + error.message)
|
||||
}
|
||||
},
|
||||
|
||||
// 取消保存
|
||||
handleCancelSave() {
|
||||
this.showSaveDialog = false
|
||||
this.filesToSave = []
|
||||
},
|
||||
async openCurveSaveDialogForSelectedFiles() {
|
||||
const paths = (this.selectedFilePaths && this.selectedFilePaths.length > 0)
|
||||
? this.selectedFilePaths
|
||||
: (this.selectedFilePath ? [this.selectedFilePath] : []);
|
||||
|
||||
if (!paths.length) {
|
||||
alert('请先选择一个或多个文件后再导出');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$refs.GuiForDataShow.openSaveCurveDialogByPaths(paths);
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式区域 */
|
||||
h1 {
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
background-color: #f3f5fa;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
12
src/DataView/appGloblefunction.js
Normal file
@ -0,0 +1,12 @@
|
||||
export default {
|
||||
install(app, options) {
|
||||
// 将整个 myFileMethod 实例挂载到全局属性 $fileUtils
|
||||
app.config.globalProperties.$fileUtils = myFileMethod;
|
||||
// 将 isElectron 函数也挂载到全局属性 $isElectron
|
||||
app.config.globalProperties.$isElectron = isElectron;
|
||||
// 如果还有其他全局组件、指令等,也可以在这里注册
|
||||
// app.component('MyGlobalComponent', MyGlobalComponent);
|
||||
// app.directive('my-directive', myDirective);
|
||||
console.log('fileUtilsPlugin 已安装');
|
||||
}
|
||||
};
|
||||
BIN
src/DataView/assets/保存曲线-未点击.png
Normal file
|
After Width: | Height: | Size: 449 B |
BIN
src/DataView/assets/保存曲线-点击.png
Normal file
|
After Width: | Height: | Size: 629 B |
BIN
src/DataView/assets/加载失败.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
1
src/DataView/assets/加载失败.svg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
src/DataView/assets/图例设置-未点击.png
Normal file
|
After Width: | Height: | Size: 763 B |
BIN
src/DataView/assets/图例设置-点击.png
Normal file
|
After Width: | Height: | Size: 978 B |
BIN
src/DataView/assets/图钉.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src/DataView/assets/文件图标-线.png
Normal file
|
After Width: | Height: | Size: 350 B |
BIN
src/DataView/assets/文件图标-面.png
Normal file
|
After Width: | Height: | Size: 673 B |
BIN
src/DataView/assets/文件夹图标.png
Normal file
|
After Width: | Height: | Size: 471 B |
BIN
src/DataView/assets/重置视图-未点击.png
Normal file
|
After Width: | Height: | Size: 489 B |
BIN
src/DataView/assets/重置视图-点击.png
Normal file
|
After Width: | Height: | Size: 662 B |
247
src/DataView/menuvue/menubar.vue
Normal file
@ -0,0 +1,247 @@
|
||||
<script>
|
||||
import { BDropdownItem, BDropdown, BDropdownDivider, BButtonGroup, BButton, BModal, BNavbar, BNavbarBrand, BNavbarNav, BNavItem, BNavItemDropdown, BToast, useToast } from 'bootstrap-vue-next';
|
||||
|
||||
import { ref, Teleport } from 'vue';
|
||||
|
||||
import EventBus from "../../eventBus.js";
|
||||
|
||||
export default {
|
||||
name: 'menubardatavue',
|
||||
components: {
|
||||
BDropdownItem,
|
||||
BDropdown,
|
||||
BDropdownDivider,
|
||||
BButtonGroup,
|
||||
BButton,
|
||||
BModal,
|
||||
BNavbar,
|
||||
BNavbarBrand,
|
||||
BNavbarNav,
|
||||
BNavItem,
|
||||
BNavItemDropdown,
|
||||
BToast
|
||||
|
||||
},
|
||||
emits: ['menubalclicked'],
|
||||
data() {
|
||||
return {
|
||||
msg: 'Welcome to Your Vue.js App',
|
||||
modal: false,
|
||||
DCbutton: {
|
||||
state: "init",
|
||||
|
||||
},
|
||||
WRbutton: {
|
||||
state: "init",
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const active = ref(false);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return { active }
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// 仅注册总线,键盘监听放在 activated
|
||||
EventBus.on('SetMenubutton', this.setbutton);
|
||||
},
|
||||
activated() {
|
||||
window.addEventListener("keydown", this.handlekeydown);
|
||||
},
|
||||
deactivated() {
|
||||
window.removeEventListener("keydown", this.handlekeydown);
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("keydown", this.handlekeydown);
|
||||
EventBus.off && EventBus.off('SetMenubutton', this.setbutton);
|
||||
},
|
||||
methods: {
|
||||
setbutton(command) {
|
||||
if (command.name == "DC") {
|
||||
this.DCbutton.state = command.state;
|
||||
}
|
||||
if (command.name == "WR") {
|
||||
this.WRbutton.state = command.state;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
showbox() {
|
||||
EventBus.emit('showbox', "hello", "提示11")
|
||||
},
|
||||
|
||||
quit() {
|
||||
EventBus.emit('triggerClearData');
|
||||
setTimeout(() => {
|
||||
EventBus.emit('changemainvue');
|
||||
}, 100);
|
||||
},
|
||||
|
||||
|
||||
changemainvue() {
|
||||
EventBus.emit('changemainvue');
|
||||
},
|
||||
|
||||
onmenuclick(type, name) {
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log("menu " + name + " click");
|
||||
// let command = {
|
||||
// name: name,
|
||||
// type: type
|
||||
// }
|
||||
// this.$emit("menubalclicked", command)
|
||||
},
|
||||
handlekeydown(event) {
|
||||
const t = event.target || {};
|
||||
const tag = (t.tagName || '').toLowerCase();
|
||||
const isEditable = t.isContentEditable || tag === 'input' || tag === 'textarea' || tag === 'select';
|
||||
if (isEditable) return;
|
||||
|
||||
// 只处理来自 #app 内部的事件,忽略外部悬浮窗/插件
|
||||
const appRoot = document.getElementById('app');
|
||||
if (!appRoot || !appRoot.contains(event.target)) return;
|
||||
|
||||
// 不劫持系统复制快捷键 Ctrl+C
|
||||
if (event.ctrlKey && !event.shiftKey && (event.key === 'c' || event.key === 'C')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.ctrlKey) {
|
||||
if (event.key == "n" || event.key == "N") {
|
||||
this.onmenuclick('Set', 'Workmode');
|
||||
}
|
||||
if (event.key == "d" || event.key == "D") {
|
||||
this.onmenuclick('Set', 'DevInfo');
|
||||
}
|
||||
if (event.key == "w" || event.key == "W") {
|
||||
this.onmenuclick('Set', 'Weavelenth');
|
||||
}
|
||||
// 与采集页保持一致:定标改为 Ctrl + Shift + C
|
||||
if (event.shiftKey && (event.key == "c" || event.key == "C")) {
|
||||
this.onmenuclick('Set', 'Calibrate');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
openFolder() {
|
||||
// 打开:先清理再打开
|
||||
EventBus.emit('triggerClearData');
|
||||
EventBus.emit('triggerOpenFolder');
|
||||
},
|
||||
|
||||
saveFiles() {
|
||||
EventBus.emit('triggerSaveFiles');
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<!--<script setup lang="ts">-->
|
||||
<!--import { BDropdownItem,BDropdown,BDropdownDivider,BButtonGroup,BButton,BModal,BNavbar,BNavbarBrand,BNavbarNav,BNavItem,BNavItemDropdown,BToast,useToast } from 'bootstrap-vue-next';-->
|
||||
<!--import { ref} from 'vue';-->
|
||||
<!--const {show1} = useToast();-->
|
||||
<!--const active = ref(false)-->
|
||||
<!--</script>-->
|
||||
<template>
|
||||
<BNavbar variant="dark" v-b-color-mode="'dark'" style="height: 3vh">
|
||||
|
||||
<BNavbarNav>
|
||||
<BNavItemDropdown text="文件" right>
|
||||
<!-- <BDropdownItem href="#">新建</BDropdownItem> -->
|
||||
<BDropdownItem href="#" @click="openFolder">打开</BDropdownItem>
|
||||
<BDropdownItem href="#" @click="saveFiles">保存</BDropdownItem>
|
||||
<!-- <BDropdownItem href="#">另存为</BDropdownItem> -->
|
||||
<BDropdownDivider></BDropdownDivider>
|
||||
<BDropdownItem href="#" @click="quit()">退出</BDropdownItem>
|
||||
<!-- <BDropdownItem href="#" @click="onmenuclick('File', 'Advance')">高级</BDropdownItem> -->
|
||||
<!-- <BDropdownItem @click="onmenuclick('info', 'help')">帮助</BDropdownItem> -->
|
||||
</BNavItemDropdown>
|
||||
|
||||
<!-- <!– Navbar dropdowns –>-->
|
||||
|
||||
|
||||
<!-- <BNavItemDropdown text="设置" right> -->
|
||||
<!-- <BDropdownItem @click="onmenuclick('Set','Workmode')">工作模式</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','DevInfo')">设备信息</BDropdownItem> -->
|
||||
<!-- <BDropdownItem @click="onmenuclick('Set','Weavelenth')">波长系数</BDropdownItem> -->
|
||||
<!-- <BDropdownItem @click="onmenuclick('Set','Weavelenthcoeff')">波长设定</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','Calibrate')">定标</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','CalibrateHH3')">HH3定标</BDropdownItem> -->
|
||||
<!-- </BNavItemDropdown> -->
|
||||
|
||||
<BNavItemDropdown text="窗口" right>
|
||||
|
||||
|
||||
<BDropdownItem @click="changemainvue()">数据采集</BDropdownItem>
|
||||
<!-- <BDropdownItem >ES</BDropdownItem>-->
|
||||
<!-- <BDropdownItem href="#">RU</BDropdownItem>-->
|
||||
<!-- <BDropdownItem href="#">FA</BDropdownItem>-->
|
||||
</BNavItemDropdown>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- <Teleport to="body">-->
|
||||
<!-- <div class="toast-container position-fixed " style="top:0px;right: 0px;width: 300px" >-->
|
||||
<!-- <BToast v-model="active" variant="info" interval="10" value="100" progress-props="{-->
|
||||
<!-- variant: 'danger',-->
|
||||
<!-- },">-->
|
||||
<!-- <template #title>-->
|
||||
<!-- Title-->
|
||||
<!-- </template>-->
|
||||
<!-- 你好-->
|
||||
<!-- </BToast>-->
|
||||
<!-- </div>-->
|
||||
<!-- </Teleport>-->
|
||||
<!-- <BButton @click="active = !active">Toggle</BButton>-->
|
||||
</BNavbarNav>
|
||||
<!-- <div class="btgroup">
|
||||
<b-button variant="secondary" pill class="siglebt" @click="onmenuclick('Work','OPT')">OPT</b-button>
|
||||
<b-button :variant='DCbutton.state=="OK"?"success":"secondary"' pill class="siglebt" @click=" onmenuclick('Work','DC') ">DC</b-button>
|
||||
|
||||
<b-button :variant='WRbutton.state=="OK"?"success":"secondary"' pill class="siglebt" @click="onmenuclick('Work','WR')">WR</b-button>
|
||||
<b-button variant="secondary" pill class="siglebt" disabled @click="onmenuclick('Work','Rad')">Rad</b-button>
|
||||
<b-button variant="secondary" pill class="siglebt" @click="onmenuclick('Work','Save')">Save</b-button>
|
||||
|
||||
</div> -->
|
||||
</BNavbar>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.navbar {
|
||||
background-color: #f8f9fa;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.btgroup {
|
||||
position: absolute;
|
||||
right: 15%;
|
||||
}
|
||||
|
||||
.siglebt {
|
||||
radio: 50%;
|
||||
font-size: 10px;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
padding: 0px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
260
src/DataView/vuecomponents/GuiForDataShow.vue
Normal file
@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<el-main style="height: 100%; width: 100%; overflow: auto;display: flex
|
||||
;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;">
|
||||
<el-row class="secondhang">
|
||||
<GuiForPlotShow @onComBox1="onComBox1" @onComBox2="onComBox2" @legendselectchanged="legendselectchanged"
|
||||
@useDarkDnChanged="onUseDarkDnChanged" ref="ASDPlotShow" class="plotcontainer">
|
||||
</GuiForPlotShow>
|
||||
</el-row>
|
||||
<el-row class="firsthang">
|
||||
<el-col :span="8" class="diveinfo">
|
||||
<GuiForDivesInfo ref="GuiForDivesInforef"></GuiForDivesInfo>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<PictureDisplayInterface ref="PictureDisplayInterfaceRef"></PictureDisplayInterface>
|
||||
<!-- <div class="imageAndMap">
|
||||
|
||||
</div>
|
||||
地图 -->
|
||||
<!-- <MapContainer></MapContainer> -->
|
||||
<!-- <a-image v-if="imgeList.length > 0" width="200" :src="imgeList[0].url" /> -->
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import GuiForPlotShow from "./GuiForPlotShow.vue";
|
||||
import GuiForDivesInfo from "./GuiForDivesInfo.vue";
|
||||
import PictureDisplayInterface from "./PictureDisplayInterface.vue";
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||||
import { spectralTypeList, spectralProcessTypeList, getIrisDataDispose } from '../../utils/irisDataDispose';
|
||||
import { SpectralDataService } from '../../utils/spectralDataService';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import EventBus from "../../eventBus.js";
|
||||
|
||||
defineOptions({
|
||||
name: "GuiForDataShow"
|
||||
});
|
||||
|
||||
const fromData = ref({
|
||||
comBox1: spectralTypeList[0].value,
|
||||
comBox2: '',
|
||||
});
|
||||
const useDarkDn = ref(true);
|
||||
const ASDPlotShow = ref(null);
|
||||
const GuiForDivesInforef = ref(null);
|
||||
const PictureDisplayInterfaceRef = ref(null);
|
||||
const spectralDataList = ref([]);
|
||||
const spectralDataForInfo = ref([]); // 新增:专供 Info/图片使用的数据
|
||||
const imgeList = ref([]);
|
||||
const fileData = ref([]);
|
||||
|
||||
async function onloaddata(data) {
|
||||
// 重置数据
|
||||
spectralDataList.value = [];
|
||||
spectralDataForInfo.value = []; // 新增:同步清空
|
||||
imgeList.value = [];
|
||||
fileData.value = [];
|
||||
if (!data || data.length === 0) {
|
||||
updateChildComponents([], [], []);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 加载文件数据
|
||||
fileData.value = await SpectralDataService.loadFileData(data);
|
||||
|
||||
// 处理数据
|
||||
await processSpectralData();
|
||||
|
||||
if (!spectralDataList.value || spectralDataList.value.length === 0) {
|
||||
const typeLabel = spectralTypeList.find(i => i.value === fromData.value.comBox1)?.label || fromData.value.comBox1;
|
||||
ElMessage.warning(`当前数据没有${typeLabel}数据`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error);
|
||||
updateChildComponents([], [], []);
|
||||
}
|
||||
}
|
||||
|
||||
async function processSpectralData() {
|
||||
try {
|
||||
const result = SpectralDataService.processSpectralData(
|
||||
fileData.value,
|
||||
fromData.value.comBox1,
|
||||
fromData.value.comBox2,
|
||||
useDarkDn.value
|
||||
);
|
||||
|
||||
|
||||
spectralDataList.value = result.spectralDataList;
|
||||
imgeList.value = result.imageList;
|
||||
|
||||
// 新增:构造独立于 spectralDataList 的 spectralDataForInfo
|
||||
if (Array.isArray(result.spectralDataList) && result.spectralDataList.length > 0) {
|
||||
spectralDataForInfo.value = result.spectralDataList;
|
||||
} else {
|
||||
// fallback:基于 fileData 提取 environmentData 作为占位项
|
||||
const envOnlyList = [];
|
||||
for (const item of fileData.value) {
|
||||
try {
|
||||
const dispose = new getIrisDataDispose(item.data, fromData.value.comBox1, useDarkDn.value);
|
||||
const env = dispose?.environmentData;
|
||||
if (env) {
|
||||
envOnlyList.push({
|
||||
name: item.name || '',
|
||||
datax: [],
|
||||
datay: [],
|
||||
environmentData: { ...env, fileName: item.name },
|
||||
isEnvironmentOnly: true
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('提取环境信息失败:', e);
|
||||
}
|
||||
}
|
||||
spectralDataForInfo.value = envOnlyList;
|
||||
}
|
||||
|
||||
updateChildComponents(
|
||||
result.processedData,
|
||||
spectralDataForInfo.value,
|
||||
result.imageList
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('处理光谱数据失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function updateChildComponents(processedData, spectralData, imageData) {
|
||||
|
||||
ASDPlotShow.value?.onloaddata(processedData, fileData.value);
|
||||
GuiForDivesInforef.value?.onloaddata(spectralData);
|
||||
PictureDisplayInterfaceRef.value?.onloaddata(imageData, spectralData);
|
||||
}
|
||||
|
||||
// 光谱类型
|
||||
const onComBox1 = async (e) => {
|
||||
fromData.value.comBox1 = e;
|
||||
await processSpectralData();
|
||||
|
||||
if (!spectralDataList.value || spectralDataList.value.length === 0) {
|
||||
const typeLabel = spectralTypeList.find(i => i.value === fromData.value.comBox1)?.label || fromData.value.comBox1;
|
||||
ElMessage.warning(`当前数据没有${typeLabel}数据`);
|
||||
}
|
||||
};
|
||||
|
||||
// 处理方式
|
||||
const onComBox2 = async (val) => {
|
||||
fromData.value.comBox2 = val;
|
||||
if (fromData.value.comBox1) {
|
||||
await processSpectralData();
|
||||
|
||||
if (!spectralDataList.value || spectralDataList.value.length === 0) {
|
||||
const typeLabel = spectralTypeList.find(i => i.value === fromData.value.comBox1)?.label || fromData.value.comBox1;
|
||||
ElMessage.warning(`当前数据没有${typeLabel}数据`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const legendselectchanged = (nameTable) => {
|
||||
if (nameTable) {
|
||||
const filteredImages = imgeList.value.filter(element => {
|
||||
if (!element || element.length === 0) return false;
|
||||
return element.some(item => {
|
||||
const str = item.name.split('.')[0];
|
||||
const str1 = (str || '').toString()?.split('_')[0];
|
||||
return nameTable.split('_')[0] === str1;
|
||||
});
|
||||
});
|
||||
const selectedSpectral = spectralDataList.value.filter(e =>
|
||||
nameTable.includes(e.name)
|
||||
);
|
||||
|
||||
if (selectedSpectral.length > 0) {
|
||||
GuiForDivesInforef.value?.onloaddata(selectedSpectral);
|
||||
PictureDisplayInterfaceRef.value?.onloaddata(filteredImages, selectedSpectral);
|
||||
}
|
||||
} else {
|
||||
GuiForDivesInforef.value?.onloaddata(spectralDataForInfo.value);
|
||||
PictureDisplayInterfaceRef.value?.onloaddata(imgeList.value, spectralDataForInfo.value);
|
||||
}
|
||||
};
|
||||
|
||||
function openSaveCurveDialog(selectedPaths) {
|
||||
const selectedNames = Array.isArray(selectedPaths)
|
||||
? selectedPaths.map(p => (p || '').toString().split(/[\\\/]/).pop()).filter(Boolean)
|
||||
: [];
|
||||
ASDPlotShow.value?.openSaveCurveDialog(selectedNames);
|
||||
}
|
||||
|
||||
function openSaveCurveDialogByPaths(selectedPaths) {
|
||||
ASDPlotShow.value?.openSaveCurveDialogByPaths(selectedPaths || []);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
onloaddata,
|
||||
openSaveCurveDialog,
|
||||
openSaveCurveDialogByPaths
|
||||
});
|
||||
|
||||
// 新增:统一清理函数,响应 triggerClearData
|
||||
function clearAll() {
|
||||
// 清空本组件状态
|
||||
spectralDataList.value = [];
|
||||
spectralDataForInfo.value = []; // 新增:同步清空
|
||||
imgeList.value = [];
|
||||
fileData.value = [];
|
||||
// 通知子组件清空
|
||||
ASDPlotShow.value?.onloaddata([], []); // 清空图表
|
||||
GuiForDivesInforef.value?.onloaddata([]); // 清空设备信息
|
||||
PictureDisplayInterfaceRef.value?.clear?.(); // 清空图片显示
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
EventBus.on('triggerClearData', clearAll);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
EventBus.off('triggerClearData', clearAll);
|
||||
});
|
||||
// 新增:接收子组件复选框切换事件
|
||||
const onUseDarkDnChanged = async (val) => {
|
||||
useDarkDn.value = !!val;
|
||||
await processSpectralData();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.plotcontainer {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.firsthang {
|
||||
height: 42%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.secondhang {
|
||||
height: 56%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.imageAndMap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FDFDFD;
|
||||
border-radius: 4px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
</style>
|
||||
264
src/DataView/vuecomponents/GuiForDivesInfo.vue
Normal file
@ -0,0 +1,264 @@
|
||||
<template>
|
||||
<div class="maincontainer">
|
||||
<div class="container_item">
|
||||
<!-- 文件名显示 -->
|
||||
<div class="filename_display">
|
||||
<img src="../assets/文件图标-面.png">
|
||||
{{ currentItem?.environmentData?.fileName || '暂无文件' }}
|
||||
</div>
|
||||
|
||||
<!-- 轮播内容区域 -->
|
||||
<div class="carousel-container">
|
||||
<!-- 左侧导航按钮 -->
|
||||
<button class="nav-button left" @click="prevItem">
|
||||
<svg t="1754038374827" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="5034" width="200" height="200">
|
||||
<path
|
||||
d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z"
|
||||
p-id="5035"></path>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- 主要内容展示 -->
|
||||
<div class="contemer_content">
|
||||
<ul style="width:175px">
|
||||
<li>时间:</li>
|
||||
<li>温度:</li>
|
||||
<li>湿度:</li>
|
||||
<li>距离:</li>
|
||||
</ul>
|
||||
<ul style="flex:1">
|
||||
<li>{{ currentItem?.environmentData?.date || '--' }}</li>
|
||||
<li>{{ currentItem?.environmentData?.temperature || '--' }}</li>
|
||||
<li>{{ currentItem?.environmentData?.humidity || '--' }}</li>
|
||||
<li>{{ currentItem?.environmentData?.height == 0 ? 0 : currentItem?.environmentData?.height || '--' }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 右侧导航按钮 -->
|
||||
<button class="nav-button right" @click="nextItem">
|
||||
<svg style="transform: rotateZ(180deg);left: 10px;" t="1754038374827" class="icon" viewBox="0 0 1024 1024"
|
||||
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5034" width="200" height="200">
|
||||
<path
|
||||
d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z"
|
||||
p-id="5035"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 轮播指示器 -->
|
||||
<!-- <div class="carousel-indicators" v-if="tableData.length > 1">
|
||||
<span
|
||||
v-for="(item, index) in tableData"
|
||||
:key="index"
|
||||
:class="{ active: currentIndex === index }"
|
||||
@click="goToItem(index)"
|
||||
></span>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
const tableData = ref([])
|
||||
const currentIndex = ref(0)
|
||||
|
||||
// 计算当前显示的项目
|
||||
const currentItem = computed(() => {
|
||||
return tableData.value[currentIndex.value] || {}
|
||||
})
|
||||
|
||||
// 加载数据方法
|
||||
const onloaddata = (jsondata) => {
|
||||
tableData.value = jsondata
|
||||
currentIndex.value = 0 // 重置到第一项
|
||||
}
|
||||
|
||||
// 上一项
|
||||
const prevItem = () => {
|
||||
if (tableData.value.length <= 1) return
|
||||
currentIndex.value = (currentIndex.value - 1 + tableData.value.length) % tableData.value.length
|
||||
}
|
||||
|
||||
// 下一项
|
||||
const nextItem = () => {
|
||||
if (tableData.value.length <= 1) return
|
||||
currentIndex.value = (currentIndex.value + 1) % tableData.value.length
|
||||
}
|
||||
|
||||
// 跳转到指定项
|
||||
const goToItem = (index) => {
|
||||
if (index >= 0 && index < tableData.value.length) {
|
||||
currentIndex.value = index
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
onloaddata
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.maincontainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FDFDFD;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
|
||||
.container_item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.filename_display {
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
font-size: 20px;
|
||||
color: #434959;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&>img {
|
||||
width: 16px;
|
||||
height: 20px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: calc(100% - 100px);
|
||||
position: relative;
|
||||
|
||||
|
||||
|
||||
.contemer_content {
|
||||
flex: 1;
|
||||
padding: 0 20px;
|
||||
font-size: 16px;
|
||||
color: #6B7181;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding-top: 20px;
|
||||
|
||||
&>ul {
|
||||
|
||||
&>li {
|
||||
text-align: right;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&>ul:nth-child(2) {
|
||||
&>li {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
ul,
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
div {
|
||||
margin: 10px 0;
|
||||
|
||||
&>span {
|
||||
color: #434959;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
width: 60px;
|
||||
height: 90px;
|
||||
background: rgba(243, 245, 250, 1);
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
justify-content: center;
|
||||
color: #6B7181;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
|
||||
&>svg {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
left: 20px;
|
||||
|
||||
&>path {
|
||||
fill: rgba(107, 113, 129, 1);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: rgba(66, 113, 238, 0.10);
|
||||
border: 1.4px solid #4271EE;
|
||||
|
||||
&>svg {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
left: 20px;
|
||||
|
||||
&>path {
|
||||
fill: rgba(66, 113, 238, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.left {
|
||||
left: 16px;
|
||||
}
|
||||
|
||||
&.right {
|
||||
right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.carousel-indicators {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: #ccc;
|
||||
margin: 0 5px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background: #434959;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1239
src/DataView/vuecomponents/GuiForPlotShow.vue
Normal file
543
src/DataView/vuecomponents/GuiLeftSider.vue
Normal file
@ -0,0 +1,543 @@
|
||||
<template>
|
||||
<div class="GuiLeftSider">
|
||||
<p class="nameList">文件列表</p>
|
||||
<div class="el-treecontain" v-if="data && data.length > 0">
|
||||
<el-tree ref="treeRef" :data="data" :props="defaultProps" class="el-treemain" highlight-current
|
||||
:expand-on-click-node="false" :default-expanded-keys="defaultExpandedKeys" @node-click="handleNodeClick"
|
||||
node-key="id">
|
||||
<template #default="{ node, data }">
|
||||
<div class="fileitem1" v-if="data.isFolder">
|
||||
<img src="../assets/文件夹图标.png">
|
||||
{{ node.label }}
|
||||
</div>
|
||||
<div class="fileitem2" v-else-if="data.isLeaf">
|
||||
<img src="../assets/文件图标-线.png">
|
||||
{{ node.label }}
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
<!-- <div class="defaultList" v-else>
|
||||
<button @click="onopendata">选择文件夹</button>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EventBus from "../../eventBus.js"
|
||||
|
||||
export default {
|
||||
name: "GuiLeftSider",
|
||||
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
},
|
||||
DefualtPath: "",
|
||||
showButton: true,
|
||||
ctrlKeyPressed: false,
|
||||
shiftKeyPressed: false,
|
||||
shiftKeyField: [],
|
||||
selectNodes: [],
|
||||
includeChildren: true,
|
||||
allFiles: [], // 存储所有解析出的文件
|
||||
lastClickedNode: null, // 记录最后点击的节点
|
||||
lastClickTime: 0, // 记录最后点击时间
|
||||
defaultExpandedKeys: [],
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
window.addEventListener("keydown", this.handleKeyDown);
|
||||
window.addEventListener("keyup", this.handleKeyUp);
|
||||
// 额外增加:用鼠标事件同步按键状态,防止 keyup 丢失导致“多选卡住”
|
||||
window.addEventListener("mousedown", this.handleMouseDown, true); // 捕获阶段更稳妥
|
||||
window.addEventListener("mouseup", this.handleMouseUp, true);
|
||||
window.addEventListener("blur", this.resetModifierKeys); // 窗口失焦时重置
|
||||
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
||||
// 事件总线
|
||||
EventBus.on('triggerOpenFolder', this.onopendata);
|
||||
EventBus.on('triggerSaveFiles', this.handleSaveFiles);
|
||||
EventBus.on('triggerClearData', this.clearData);
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener("keydown", this.handleKeyDown);
|
||||
window.removeEventListener("keyup", this.handleKeyUp);
|
||||
// 配套移除新增的监听
|
||||
window.removeEventListener("mousedown", this.handleMouseDown, true);
|
||||
window.removeEventListener("mouseup", this.handleMouseUp, true);
|
||||
window.removeEventListener("blur", this.resetModifierKeys);
|
||||
document.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
||||
EventBus.off('triggerOpenFolder', this.onopendata);
|
||||
EventBus.off('triggerSaveFiles', this.handleSaveFiles);
|
||||
EventBus.off('triggerClearData', this.clearData);
|
||||
},
|
||||
methods: {
|
||||
handleKeyDown(event) {
|
||||
if (event.key == "Control") {
|
||||
this.ctrlKeyPressed = true;
|
||||
}
|
||||
if (event.key == "Shift") {
|
||||
this.shiftKeyPressed = true;
|
||||
}
|
||||
},
|
||||
handleKeyUp(event) {
|
||||
if (event.key == "Control") {
|
||||
this.ctrlKeyPressed = false;
|
||||
}
|
||||
if (event.key == "Shift") {
|
||||
this.shiftKeyPressed = false;
|
||||
}
|
||||
},
|
||||
// 新增:鼠标按下/松开时同步 Ctrl/Shift 状态(点击流程更可靠)
|
||||
handleMouseDown(e) {
|
||||
this.ctrlKeyPressed = !!e.ctrlKey;
|
||||
this.shiftKeyPressed = !!e.shiftKey;
|
||||
},
|
||||
handleMouseUp(e) {
|
||||
// 鼠标抬起时再次以实际状态为准(若用户已松开 Ctrl/Shift,这里会回到 false)
|
||||
this.ctrlKeyPressed = !!e.ctrlKey;
|
||||
this.shiftKeyPressed = !!e.shiftKey;
|
||||
},
|
||||
// 新增:窗口不可见/失焦时,重置修饰键,避免卡住
|
||||
handleVisibilityChange() {
|
||||
if (document.visibilityState !== 'visible') {
|
||||
this.resetModifierKeys();
|
||||
}
|
||||
},
|
||||
resetModifierKeys() {
|
||||
this.ctrlKeyPressed = false;
|
||||
this.shiftKeyPressed = false;
|
||||
},
|
||||
collectAllFiles(node) {
|
||||
const files = [];
|
||||
|
||||
if (node.isLeaf) {
|
||||
files.push({
|
||||
id: node.id,
|
||||
path: node.path,
|
||||
label: node.label
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
if (node.children && node.children.length > 0) {
|
||||
for (const child of node.children) {
|
||||
const childFiles = this.collectAllFiles(child);
|
||||
files.push(...childFiles);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
},
|
||||
isFolder(nodeData) {
|
||||
return nodeData.isFolder === true || (nodeData.children && Array.isArray(nodeData.children));
|
||||
},
|
||||
|
||||
// 添加双击事件处理
|
||||
handleNodeDblClick(nodeData, node) {
|
||||
if (nodeData.isLeaf && !this.isFolder(nodeData)) {
|
||||
// 双击文件时,发送NodeDblClicked事件
|
||||
this.$emit("NodeDblClicked", nodeData.path);
|
||||
} else if (this.isFolder(nodeData)) {
|
||||
// 双击文件夹时,收集所有文件并发送FolderDblClicked事件
|
||||
this.allFiles = this.collectAllFiles(nodeData);
|
||||
const allPaths = this.allFiles.map(file => file.path);
|
||||
this.$emit("FolderDblClicked", nodeData.path, allPaths);
|
||||
}
|
||||
},
|
||||
// 节点点击事件处理
|
||||
handleNodeClick(nodeData, node) {
|
||||
const treeRef = this.$refs.treeRef;
|
||||
if (!treeRef) return;
|
||||
|
||||
const nodes = treeRef.store._getAllNodes(); // 所有node节点
|
||||
const ishas = this.selectNodes.includes(node.id);
|
||||
const isSameLevel = (node1, node2) => node1.parent === node2.parent;
|
||||
const isNodeFolder = this.isFolder(nodeData);
|
||||
|
||||
// 实现双击检测
|
||||
const now = new Date().getTime();
|
||||
const isDoubleClick = this.lastClickedNode === nodeData.path && (now - this.lastClickTime) < 300; // 300ms内的点击视为双击
|
||||
|
||||
// 更新最后点击的节点和时间
|
||||
this.lastClickedNode = nodeData.path;
|
||||
this.lastClickTime = now;
|
||||
|
||||
// 如果是双击,则发送双击事件
|
||||
if (isDoubleClick) {
|
||||
if (nodeData.isLeaf && !isNodeFolder) {
|
||||
this.$emit("NodeDblClicked", nodeData.path);
|
||||
return; // 双击时不执行单击逻辑
|
||||
} else if (isNodeFolder) {
|
||||
// 双击文件夹时,收集所有文件并发送FolderDblClicked事件
|
||||
this.allFiles = this.collectAllFiles(nodeData);
|
||||
const allPaths = this.allFiles.map(file => file.path);
|
||||
this.$emit("FolderDblClicked", nodeData.path, allPaths);
|
||||
return; // 双击时不执行单击逻辑
|
||||
}
|
||||
}
|
||||
|
||||
// 单选模式
|
||||
if (!this.ctrlKeyPressed && !this.shiftKeyPressed) {
|
||||
// 清空之前的选择
|
||||
this.shiftKeyField = [];
|
||||
this.selectNodes = [];
|
||||
|
||||
// 如果是文件,直接选中
|
||||
if (nodeData.isLeaf && !isNodeFolder) {
|
||||
this.selectNodes = [node.id];
|
||||
this.$emit("NodeClicked", nodeData.path);
|
||||
}
|
||||
// 如果是文件夹,解析所有子文件
|
||||
else if (isNodeFolder) {
|
||||
this.selectNodes = [node.id];
|
||||
// 收集文件夹下所有文件
|
||||
this.allFiles = this.collectAllFiles(nodeData);
|
||||
// console.log('文件夹下所有文件:', this.allFiles);
|
||||
// 可以发送所有文件路径给父组件
|
||||
const allPaths = this.allFiles.map(file => file.path);
|
||||
this.$emit("FolderClicked", nodeData.path, allPaths);
|
||||
}
|
||||
}
|
||||
// Shift多选模式
|
||||
else if (this.shiftKeyPressed) {
|
||||
if (isNodeFolder) {
|
||||
this.shiftKeyField = [];
|
||||
this.selectNodes = [];
|
||||
|
||||
for (const item of nodes) {
|
||||
item.isCurrent = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果selectNodes有值但shiftKeyField为空,说明是从单选模式切换到Shift多选模式
|
||||
// 需要将已选中的节点ID添加到shiftKeyField中
|
||||
if (this.selectNodes.length > 0 && this.shiftKeyField.length === 0) {
|
||||
const firstSelectedNodeId = this.selectNodes[0];
|
||||
this.shiftKeyField.push(firstSelectedNodeId);
|
||||
}
|
||||
|
||||
if (this.selectNodes.length > 0) {
|
||||
const firstSelectedNodeId = this.selectNodes[0];
|
||||
const firstSelectedNode = nodes.find(x => x.id == firstSelectedNodeId);
|
||||
|
||||
if (firstSelectedNode && !isSameLevel(firstSelectedNode, node)) {
|
||||
this.shiftKeyField = [];
|
||||
this.selectNodes = [];
|
||||
|
||||
for (const item of nodes) {
|
||||
item.isCurrent = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.shiftKeyField.push(node.id);
|
||||
|
||||
if (this.shiftKeyField.length > 1) {
|
||||
const firstNodeId = this.shiftKeyField[0];
|
||||
const firstNode = nodes.find(x => x.id == firstNodeId);
|
||||
|
||||
if (!isSameLevel(firstNode, node)) {
|
||||
this.shiftKeyField = [];
|
||||
this.selectNodes = [];
|
||||
|
||||
for (const item of nodes) {
|
||||
item.isCurrent = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const sIndex = nodes.findIndex(x => x.id == this.shiftKeyField[0]);
|
||||
const eIndex = nodes.findIndex(x => x.id == this.shiftKeyField[this.shiftKeyField.length - 1]);
|
||||
const s = sIndex < eIndex ? sIndex : eIndex; // 取小值当开头索引
|
||||
const e = sIndex < eIndex ? eIndex : sIndex; // 取大值当结尾索引
|
||||
|
||||
for (let i = s; i <= e; i++) {
|
||||
const currentNode = nodes[i];
|
||||
if (!this.isFolder(currentNode.data) && isSameLevel(currentNode, firstNode)) {
|
||||
if (!this.selectNodes.includes(currentNode.id)) {
|
||||
this.selectNodes.push(currentNode.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isNodeFolder) {
|
||||
if (!this.selectNodes.includes(node.id)) {
|
||||
this.selectNodes.push(node.id);
|
||||
}
|
||||
} else {
|
||||
this.shiftKeyField = [];
|
||||
this.selectNodes = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
// ctrl多选模式
|
||||
else if (this.ctrlKeyPressed) {
|
||||
if (isNodeFolder) {
|
||||
this.shiftKeyField = [];
|
||||
this.selectNodes = [];
|
||||
|
||||
for (const item of nodes) {
|
||||
item.isCurrent = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ishas) {
|
||||
const index = this.selectNodes.findIndex(x => x == node.id);
|
||||
this.selectNodes.splice(index, 1);
|
||||
} else {
|
||||
this.selectNodes.push(node.id);
|
||||
}
|
||||
}
|
||||
|
||||
for (const item of nodes) {
|
||||
if (this.selectNodes.includes(item.id)) {
|
||||
item.isCurrent = true;
|
||||
} else {
|
||||
item.isCurrent = false;
|
||||
}
|
||||
}
|
||||
|
||||
const selectedNodesInfo = nodes
|
||||
.filter(item => this.selectNodes.includes(item.id))
|
||||
.map(item => ({
|
||||
id: item.id,
|
||||
label: item.label,
|
||||
path: item.data.path || '',
|
||||
isFolder: this.isFolder(item.data)
|
||||
}));
|
||||
|
||||
const selectedFiles = selectedNodesInfo.filter(item => !item.isFolder);
|
||||
if (selectedFiles.length > 0) {
|
||||
const filePaths = selectedFiles.map(file => file.path);
|
||||
this.$emit("FilesSelected", filePaths);
|
||||
}
|
||||
},
|
||||
|
||||
async onopendata() {
|
||||
try {
|
||||
// 获取文件夹列表
|
||||
this.$emit("reset");
|
||||
this.data = []
|
||||
const folderTree = await this.$tauriApi.getFolderList(this.DefualtPath);
|
||||
|
||||
const getComparableLabel = (node) => {
|
||||
if (typeof node?.label !== "string") return "";
|
||||
if (node.isLeaf) {
|
||||
return node.label.replace(/\.[^/.]+$/, "");
|
||||
}
|
||||
return node.label;
|
||||
};
|
||||
|
||||
// 工具:从名称中提取日期(YYYY[_-]M[M]?[_-]D[D]?),返回时间戳,未匹配返回 null
|
||||
const extractDateStamp = (node) => {
|
||||
const base = getComparableLabel(node);
|
||||
// 支持 2025_9_3、2025-9-3、2025_09_03、2025-09-03
|
||||
const m = base.match(/(\d{4})[_-](\d{1,2})[_-](\d{1,2})/);
|
||||
if (!m) return null;
|
||||
const y = parseInt(m[1], 10);
|
||||
const M = parseInt(m[2], 10);
|
||||
const d = parseInt(m[3], 10);
|
||||
const dt = new Date(y, M - 1, d);
|
||||
if (
|
||||
Number.isNaN(dt.getTime()) ||
|
||||
dt.getFullYear() !== y ||
|
||||
dt.getMonth() !== (M - 1) ||
|
||||
dt.getDate() !== d
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return dt.getTime();
|
||||
};
|
||||
|
||||
// 添加唯一ID,并进行过滤 + 排序(同级文件夹与文件按日期由近到远,无日期排后且保持原序)
|
||||
let idCounter = 1;
|
||||
const addUniqueIdsAndFilter = (node) => {
|
||||
node.id = idCounter++;
|
||||
if (node.isFolder) {
|
||||
if (Array.isArray(node.children) && node.children.length) {
|
||||
// 过滤:仅保留文件夹与 .iris 文件
|
||||
node.children = node.children.filter(child => {
|
||||
if (child.isFolder) return true;
|
||||
if (child.isLeaf && typeof child.label === "string") {
|
||||
return child.label.endsWith(".iris");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// 排序:按包含的日期(忽略后缀)由近到远;无日期排在后面并保持原有顺序
|
||||
const decorated = node.children.map((child, idx) => ({
|
||||
child,
|
||||
idx,
|
||||
stamp: extractDateStamp(child) // number | null
|
||||
}));
|
||||
decorated.sort((a, b) => {
|
||||
const aHas = typeof a.stamp === "number";
|
||||
const bHas = typeof b.stamp === "number";
|
||||
if (aHas && bHas) {
|
||||
return b.stamp - a.stamp; // 近(新) -> 远(旧)
|
||||
}
|
||||
if (aHas && !bHas) return -1; // 有日期在前
|
||||
if (!aHas && bHas) return 1; // 无日期在后
|
||||
// 都没有日期:保持原有顺序(稳定)
|
||||
return a.idx - b.idx;
|
||||
});
|
||||
node.children = decorated.map(d => d.child);
|
||||
|
||||
// 递归处理
|
||||
node.children.forEach(child => addUniqueIdsAndFilter(child));
|
||||
}
|
||||
} else {
|
||||
// 非文件夹无需处理子项
|
||||
}
|
||||
};
|
||||
|
||||
addUniqueIdsAndFilter(folderTree);
|
||||
|
||||
if (folderTree && folderTree.label != "请选择") {
|
||||
this.data = [folderTree];
|
||||
}
|
||||
|
||||
// 收集所有id用于默认展开
|
||||
const expandedKeys = [];
|
||||
this.collectAllNodeIds(folderTree, expandedKeys);
|
||||
this.defaultExpandedKeys = expandedKeys;
|
||||
} catch (error) {
|
||||
console.error("打开文件夹失败:", error);
|
||||
}
|
||||
},
|
||||
|
||||
// 整合所有节点id,默认显示使用
|
||||
collectAllNodeIds(node, arr) {
|
||||
arr.push(node.id);
|
||||
if (node.children && node.children.length > 0) {
|
||||
node.children.forEach(child => this.collectAllNodeIds(child, arr));
|
||||
}
|
||||
},
|
||||
// 处理保存文件事件
|
||||
handleSaveFiles() {
|
||||
const selectedFiles = this.getSelectedFiles();
|
||||
if (selectedFiles.length === 0) {
|
||||
alert('请先打开文件后再保存')
|
||||
return;
|
||||
}
|
||||
// 触发保存文件请求事件,传递选中的文件
|
||||
this.$emit('SaveFilesRequested', selectedFiles);
|
||||
},
|
||||
|
||||
// 获取文件
|
||||
getSelectedFiles() {
|
||||
const treeRef = this.$refs.treeRef;
|
||||
if (!treeRef) return [];
|
||||
const nodes = treeRef.store._getAllNodes();
|
||||
const allFiles = [];
|
||||
|
||||
// 遍历所有节点,收集所有文件
|
||||
nodes.forEach(node => {
|
||||
if (node.data && node.data.isLeaf && !node.data.isFolder) {
|
||||
allFiles.push({
|
||||
id: node.id,
|
||||
label: node.data.label,
|
||||
path: node.data.path,
|
||||
name: node.data.label
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return allFiles;
|
||||
},
|
||||
|
||||
// 清空数据
|
||||
clearData() {
|
||||
this.$emit("reset");
|
||||
this.data = []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
el-tree {
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.el-treemain {
|
||||
min-width: 100%;
|
||||
white-space: nowrap;
|
||||
/* 不换行,使树节点水平排列 */
|
||||
display: inline-block;
|
||||
/* 横向排列 */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.el-treecontain {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
max-height: 88vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.fileitem1 {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&>img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.fileitem2 {
|
||||
width: 100%;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&>img {
|
||||
margin-right: 5px;
|
||||
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.fileitem:nth-child(2) {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
.GuiLeftSider {
|
||||
padding: 17px 24px;
|
||||
}
|
||||
|
||||
.GuiLeftSider p {
|
||||
font-size: 18px;
|
||||
color: #434959;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.defaultList button {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
border-radius: 4px;
|
||||
border: 1.4px solid #4271EE;
|
||||
box-shadow: none;
|
||||
font-size: 16px;
|
||||
color: #4271EE;
|
||||
}
|
||||
</style>
|
||||
40
src/DataView/vuecomponents/HelloWorld.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps({
|
||||
msg: String,
|
||||
})
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<div class="card">
|
||||
<button type="button" @click="count++">count is {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test HMR
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Check out
|
||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||
>create-vue</a
|
||||
>, the official Vue + Vite starter
|
||||
</p>
|
||||
<p>
|
||||
Install
|
||||
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
||||
in your IDE for a better DX
|
||||
</p>
|
||||
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
251
src/DataView/vuecomponents/MapContainer.vue
Normal file
@ -0,0 +1,251 @@
|
||||
<template>
|
||||
<div ref="mapContainer" class="ol-map-wrapper">
|
||||
<div class="ol-map" ref="olMap"></div>
|
||||
<button class="fullscreen-btn" @click="toggleFullScreen">
|
||||
{{ isFullscreen ? '退出全屏' : '全屏显示' }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount, defineProps, watch } from 'vue';
|
||||
import 'ol/ol.css';
|
||||
import { Map, View } from 'ol';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
import XYZ from 'ol/source/XYZ';
|
||||
import { Feature } from 'ol';
|
||||
import Point from 'ol/geom/Point';
|
||||
import VectorSource from 'ol/source/Vector';
|
||||
import VectorLayer from 'ol/layer/Vector';
|
||||
import { Icon, Style, Text, Fill, Stroke } from 'ol/style';
|
||||
import { fromLonLat } from 'ol/proj';
|
||||
import pinIcon from '../assets/图钉.png';
|
||||
import { boundingExtent } from 'ol/extent';
|
||||
|
||||
const props = defineProps({
|
||||
dataListMap: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const mapContainer = ref(null);
|
||||
const olMap = ref(null)
|
||||
const map = ref(null);
|
||||
const vectorLayer = ref(null);
|
||||
const isMapReady = ref(false);
|
||||
const isFullscreen = ref(false);
|
||||
|
||||
|
||||
const initializeMap = () => {
|
||||
const center = fromLonLat([116.255535, 40.204654]);
|
||||
|
||||
const view = new View({
|
||||
center,
|
||||
zoom: 14
|
||||
});
|
||||
|
||||
const tiandituKey = 'a155b662f47ceee8d82a67bfbb3a0825';
|
||||
|
||||
const tileLayers = [
|
||||
new TileLayer({
|
||||
source: new XYZ({
|
||||
url: `http://t{0-7}.tianditu.gov.cn/DataServer/wmts?T=img_w&x={x}&y={y}&l={z}&tk=${tiandituKey}`
|
||||
}),
|
||||
isBaseLayer: true
|
||||
}),
|
||||
new TileLayer({
|
||||
source: new XYZ({
|
||||
url: `http://t{0-7}.tianditu.gov.cn/DataServer/wmts?T=cia_w&x={x}&y={y}&l={z}&tk=${tiandituKey}`
|
||||
}),
|
||||
isBaseLayer: true
|
||||
})
|
||||
];
|
||||
|
||||
const vectorSource = new VectorSource();
|
||||
vectorLayer.value = new VectorLayer({
|
||||
source: vectorSource
|
||||
});
|
||||
|
||||
map.value = new Map({
|
||||
target: olMap.value,
|
||||
layers: [...tileLayers, vectorLayer.value],
|
||||
view
|
||||
});
|
||||
|
||||
isMapReady.value = true;
|
||||
};
|
||||
|
||||
const getRandomCoordinateInBeijing = () => {
|
||||
const minLon = 115.7;
|
||||
const maxLon = 117.4;
|
||||
const minLat = 40.2;
|
||||
const maxLat = 40.5;
|
||||
|
||||
const lon = Math.random() * (maxLon - minLon) + minLon;
|
||||
const lat = Math.random() * (maxLat - minLat) + minLat;
|
||||
|
||||
return {
|
||||
longitude: parseFloat(lon.toFixed(6)),
|
||||
latitude: parseFloat(lat.toFixed(6))
|
||||
};
|
||||
};
|
||||
|
||||
const handleTagging = (data) => {
|
||||
if (!isMapReady.value || !Array.isArray(data)) return;
|
||||
|
||||
const features = [];
|
||||
const coords = [];
|
||||
|
||||
data.forEach(item => {
|
||||
const { longitude, latitude } = getRandomCoordinateInBeijing(); // 模拟
|
||||
if (longitude && latitude) {
|
||||
const feature = new Feature({
|
||||
geometry: new Point(fromLonLat([longitude, latitude])),
|
||||
name: item.environmentData.fileName || ''
|
||||
});
|
||||
|
||||
feature.setStyle(
|
||||
new Style({
|
||||
image: new Icon({
|
||||
src: pinIcon,
|
||||
anchor: [0.5, 1],
|
||||
scale: 1
|
||||
}),
|
||||
text: new Text({
|
||||
text: item.environmentData.fileName || '',
|
||||
offsetY: 14,
|
||||
font: '300 14px sans-serif',
|
||||
fill: new Fill({
|
||||
color: '#fff'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#fff',
|
||||
width: 0
|
||||
}),
|
||||
textAlign: 'center',
|
||||
backgroundFill: new Fill({
|
||||
color: 'rgba(0, 0, 0, 0.5)'
|
||||
}),
|
||||
backgroundStroke: new Stroke({
|
||||
color: 'rgba(0, 0, 0, 0.5)',
|
||||
width: 0
|
||||
}),
|
||||
padding: [1, 10, 1, 10],
|
||||
radius: 4
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
features.push(feature);
|
||||
coords.push(fromLonLat([longitude, latitude]));
|
||||
}
|
||||
});
|
||||
|
||||
if (features.length > 0) {
|
||||
vectorLayer.value.getSource().clear();
|
||||
vectorLayer.value.getSource().addFeatures(features);
|
||||
|
||||
const extent = boundingExtent(coords);
|
||||
map.value.getView().fit(extent, {
|
||||
padding: [50, 50, 50, 50],
|
||||
maxZoom: 16,
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const toggleFullScreen = () => {
|
||||
const container = mapContainer.value;
|
||||
|
||||
if (!document.fullscreenElement) {
|
||||
container?.requestFullscreen?.();
|
||||
} else {
|
||||
document.exitFullscreen?.();
|
||||
}
|
||||
};
|
||||
|
||||
const fullscreenChangeHandler = () => {
|
||||
isFullscreen.value = !!document.fullscreenElement;
|
||||
};
|
||||
|
||||
// 新增:清空地图矢量图层的方法
|
||||
const clearMap = () => {
|
||||
if (vectorLayer.value && vectorLayer.value.getSource()) {
|
||||
vectorLayer.value.getSource().clear();
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataListMap,
|
||||
(newVal) => {
|
||||
// 当传入空数组或非法数据时,清空图层中的点
|
||||
if (!Array.isArray(newVal) || newVal.length === 0) {
|
||||
clearMap();
|
||||
return;
|
||||
}
|
||||
|
||||
const tryAdd = () => {
|
||||
if (isMapReady.value) {
|
||||
handleTagging(newVal);
|
||||
} else {
|
||||
setTimeout(tryAdd, 100);
|
||||
}
|
||||
};
|
||||
|
||||
tryAdd();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
try {
|
||||
initializeMap();
|
||||
} catch (error) {
|
||||
alert('初始化地图出错,', error)
|
||||
}
|
||||
document.addEventListener('fullscreenchange', fullscreenChangeHandler);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('fullscreenchange', fullscreenChangeHandler);
|
||||
});
|
||||
|
||||
// 对外暴露清空方法,供父组件调用
|
||||
defineExpose({
|
||||
clearMap
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ol-map-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ol-map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fullscreen-btn {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 1000;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
270
src/DataView/vuecomponents/PictureDisplayInterface.vue
Normal file
@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<div class="maincontainer">
|
||||
<div class="container_item">
|
||||
<!-- 文件名显示 -->
|
||||
<div class="filename_display" v-if="!isLastPage">
|
||||
<img src="../assets/文件图标-面.png">
|
||||
{{ currentItem?.name || '暂无文件' }}
|
||||
</div>
|
||||
<div class="filename_display" v-else>
|
||||
地图
|
||||
</div>
|
||||
<!-- 轮播内容区域 -->
|
||||
<div class="carousel-container">
|
||||
<!-- 左侧导航按钮 -->
|
||||
<button class="nav-button left" @click="prevItem">
|
||||
<svg t="1754038374827" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" p-id="5034" width="200" height="200">
|
||||
<path
|
||||
d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z"
|
||||
p-id="5035"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="contemer_content">
|
||||
<div class="jzsb" v-if="!isLastPage && currentItem.url == 'jzsb'">
|
||||
<img src="../assets/加载失败.svg"></img>
|
||||
<span>图片加载失败</span>
|
||||
</div>
|
||||
<img v-else-if="!isLastPage" :src="currentItem.url" />
|
||||
<div v-else class="last-page-box">
|
||||
<MapContainer ref="mapRef" :dataListMap="dataListMap"></MapContainer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧导航按钮 -->
|
||||
<button class="nav-button right" @click="nextItem">
|
||||
<svg style="transform: rotateZ(180deg);left: 10px;" t="1754038374827" class="icon"
|
||||
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5034" width="200"
|
||||
height="200">
|
||||
<path
|
||||
d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z"
|
||||
p-id="5035"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import MapContainer from "./MapContainer.vue";
|
||||
|
||||
const imgeList = ref([])
|
||||
const currentIndex = ref(0)
|
||||
const dataListMap = ref([])
|
||||
const mapRef = ref(null)
|
||||
const isLastPage = computed(() => currentIndex.value === imgeList.value.length)
|
||||
|
||||
const currentItem = computed(() => {
|
||||
if (isLastPage.value) {
|
||||
return {}
|
||||
}
|
||||
return imgeList.value[currentIndex.value] || {}
|
||||
})
|
||||
|
||||
|
||||
const onloaddata = async (jsondata, dataList) => {
|
||||
if (jsondata && jsondata.length > 0 && dataList && dataList.length > 0) {
|
||||
dataListMap.value = dataList
|
||||
imgeList.value = jsondata.flat()
|
||||
currentIndex.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:清空方法,确保图片与地图点都能被清理
|
||||
const clear = () => {
|
||||
imgeList.value = []
|
||||
dataListMap.value = []
|
||||
currentIndex.value = 0
|
||||
mapRef.value?.clearMap()
|
||||
}
|
||||
|
||||
|
||||
// 上一项
|
||||
const prevItem = () => {
|
||||
if (imgeList.value.length === 0) return
|
||||
currentIndex.value =
|
||||
(currentIndex.value - 1 + (imgeList.value.length + 1)) %
|
||||
(imgeList.value.length + 1)
|
||||
}
|
||||
|
||||
// 下一项
|
||||
const nextItem = () => {
|
||||
if (imgeList.value.length === 0) return
|
||||
currentIndex.value = (currentIndex.value + 1) % (imgeList.value.length + 1)
|
||||
}
|
||||
|
||||
// 跳转到指定项
|
||||
const goToItem = (index) => {
|
||||
if (index >= 0 && index < imgeList.value.length) {
|
||||
currentIndex.value = index
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
onloaddata,
|
||||
clear
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.maincontainer {
|
||||
width: 97.5%;
|
||||
height: 100%;
|
||||
background: #FDFDFD;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
float: right;
|
||||
|
||||
.container_item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.filename_display {
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
font-size: 20px;
|
||||
color: #434959;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&>img {
|
||||
width: 16px;
|
||||
height: 20px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: calc(100% - 100px);
|
||||
position: relative;
|
||||
|
||||
|
||||
|
||||
.contemer_content {
|
||||
flex: 1;
|
||||
padding: 0 20px;
|
||||
font-size: 18px;
|
||||
color: #6B7181;
|
||||
width: 100%;
|
||||
height: 30vh;
|
||||
display: flex;
|
||||
// padding-top: 20px;
|
||||
|
||||
&>img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
&>.last-page-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
& > .jzsb {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&>img {
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
}
|
||||
&>span {
|
||||
font-size: 14px;
|
||||
color: #6B7181;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
width: 60px;
|
||||
height: 90px;
|
||||
background: rgba(243, 245, 250, 1);
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
justify-content: center;
|
||||
color: #6B7181;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
&>svg {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
left: 20px;
|
||||
|
||||
&>path {
|
||||
fill: rgba(107, 113, 129, 1);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: rgba(66, 113, 238, 0.10);
|
||||
border: 1.4px solid #4271EE;
|
||||
|
||||
&>svg {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
left: 20px;
|
||||
|
||||
&>path {
|
||||
fill: rgba(66, 113, 238, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.left {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
&.right {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-indicators {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: #ccc;
|
||||
margin: 0 5px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background: #434959;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
301
src/DataView/vuecomponents/SaveFileDialog.vue
Normal file
@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<el-dialog style="padding: 0 ; border-radius: 12px; overflow: hidden; min-width:600px; max-width:800px"
|
||||
class="legend_my_el_dialog" v-model="showModal" width="24%" @close="handleCancel">
|
||||
<template #title>
|
||||
<div class="legend-dialog-title">保存文件</div>
|
||||
</template>
|
||||
<div class="save-dialog-content">
|
||||
<div class="file-selection-section">
|
||||
<div class="select-all-section">
|
||||
<h6>选择要保存的文件</h6>
|
||||
<el-checkbox class="my_save_checkbox select-all-checkbox" v-model="selectAll"
|
||||
:indeterminate="isIndeterminate" @change="handleSelectAll">
|
||||
全选
|
||||
</el-checkbox>
|
||||
</div>
|
||||
<div class="file-list">
|
||||
<div>
|
||||
<div v-for="file in selectedFiles" :key="file.path" class="file-item">
|
||||
<el-checkbox class="my_save_checkbox" v-model="file.selected" :label="file.label"
|
||||
@change="handleFileSelect">
|
||||
{{ file.label }}
|
||||
</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="save-location-section">
|
||||
<h6>保存位置</h6>
|
||||
<div class="location-input">
|
||||
<el-input v-model="saveLocation" placeholder="请选择保存位置">
|
||||
</el-input>
|
||||
<el-button @click="selectSaveLocation" class="input-group-button">浏览</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="save-actions">
|
||||
<el-button type="primary" @click="handleSave" class="input-group-button-primary">保存</el-button>
|
||||
<el-button @click="handleCancel" class="input-group-button">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { dialog } from '@tauri-apps/api'
|
||||
|
||||
export default {
|
||||
name: 'SaveFileDialog',
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
emits: ['update:visible', 'save', 'cancel'],
|
||||
data() {
|
||||
return {
|
||||
saveLocation: '',
|
||||
selectedFiles: [],
|
||||
selectAll: false,
|
||||
isIndeterminate: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showModal: {
|
||||
get() {
|
||||
return this.visible
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:visible', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
files: {
|
||||
handler(newFiles) {
|
||||
this.selectedFiles = newFiles.map(file => ({
|
||||
...file,
|
||||
selected: true
|
||||
}))
|
||||
this.updateSelectAllState()
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async selectSaveLocation() {
|
||||
try {
|
||||
const selected = await dialog.open({
|
||||
directory: true,
|
||||
title: '选择保存位置'
|
||||
})
|
||||
if (selected) {
|
||||
this.saveLocation = selected
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('选择保存位置失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
handleSave() {
|
||||
const filesToSave = this.selectedFiles.filter(file => file.selected)
|
||||
if (filesToSave.length === 0) {
|
||||
// this.$message.warning('请至少选择一个文件')
|
||||
alert('请至少选择一个文件')
|
||||
return
|
||||
}
|
||||
if (!this.saveLocation) {
|
||||
alert('请选择保存位置')
|
||||
// this.$message.warning('请选择保存位置')
|
||||
return
|
||||
}
|
||||
|
||||
this.$emit('save', {
|
||||
files: filesToSave,
|
||||
location: this.saveLocation
|
||||
})
|
||||
this.showModal = false
|
||||
},
|
||||
|
||||
handleCancel() {
|
||||
this.$emit('cancel')
|
||||
this.showModal = false
|
||||
},
|
||||
|
||||
handleSelectAll(value) {
|
||||
this.selectedFiles.forEach(file => {
|
||||
file.selected = value
|
||||
})
|
||||
this.updateSelectAllState()
|
||||
},
|
||||
|
||||
handleFileSelect() {
|
||||
this.updateSelectAllState()
|
||||
},
|
||||
|
||||
updateSelectAllState() {
|
||||
const selectedCount = this.selectedFiles.filter(file => file.selected).length
|
||||
const totalCount = this.selectedFiles.length
|
||||
|
||||
if (selectedCount === 0) {
|
||||
this.selectAll = false
|
||||
this.isIndeterminate = false
|
||||
} else if (selectedCount === totalCount) {
|
||||
this.selectAll = true
|
||||
this.isIndeterminate = false
|
||||
} else {
|
||||
this.selectAll = false
|
||||
this.isIndeterminate = true
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.file-selection-section,
|
||||
.save-location-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
h6 {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.select-all-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.file-list {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.file-item {
|
||||
margin-bottom: 8px;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
text-align: left;
|
||||
|
||||
}
|
||||
|
||||
.file-item:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.file-path {
|
||||
color: #606266;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.no-files-message {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.location-input {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.legend_my_el_dialog {
|
||||
.el-dialog__header.show-close {
|
||||
padding: 0 !important;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
|
||||
.el-dialog__headerbtn {
|
||||
box-shadow: none;
|
||||
top: 4px;
|
||||
right: 14px;
|
||||
font-size: 24px;
|
||||
color: #000;
|
||||
|
||||
.el-icon {
|
||||
fill: #000;
|
||||
|
||||
path {
|
||||
fill: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.legend-dialog-title {
|
||||
text-align: left;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
background: #F3F5FA;
|
||||
border-radius: 12px 12px 0px 0px;
|
||||
padding: 0;
|
||||
font-weight: 600;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.save-dialog-content {
|
||||
padding: 20px 0;
|
||||
|
||||
.my_save_checkbox {
|
||||
.el-checkbox__input.is-checked+.el-checkbox__label {
|
||||
color: #4271EE;
|
||||
}
|
||||
|
||||
.el-checkbox__input.is-checked .el-checkbox__inner {
|
||||
border-color: #4271EE;
|
||||
background-color: #4271EE;
|
||||
}
|
||||
|
||||
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
|
||||
background-color: #4271EE;
|
||||
border-color: #4271EE;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__wrapper.is-focus {
|
||||
box-shadow: 0 0 0 1px #dcdfe6;
|
||||
}
|
||||
|
||||
|
||||
.input-group-button {
|
||||
margin-left: 10px;
|
||||
box-shadow: none;
|
||||
background-color: #EDF1FB;
|
||||
color: #6B7181;
|
||||
border: 1px solid #D3D8E3;
|
||||
}
|
||||
|
||||
.input-group-button-primary {
|
||||
box-shadow: none;
|
||||
color: #fff;
|
||||
background-color: #4271EE;
|
||||
}
|
||||
|
||||
.el-button:hover {
|
||||
color: #6B7181;
|
||||
border-color: #aaabad;
|
||||
}
|
||||
|
||||
.input-group-button-primary:hover {
|
||||
color: #fff;
|
||||
border-color: #4271EE;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -7,6 +7,10 @@ import setWavelenth from "./components/menubox/SetWavelenth.vue";
|
||||
import SetName from "./components/menubox/SetName.vue";
|
||||
import SetWorkmode from "./components/menubox/SetWorkmode.vue";
|
||||
import setCalibrate from "./components/menubox/SetCalibrate.vue";
|
||||
import setCalibrateHH3 from "./components/menubox/SetCalibrateHH3.vue";
|
||||
import setWavelenthCoeff from "./components/menubox/SetWavelenthcoeff.vue";
|
||||
import ReflectanceToIris from "./components/menubox/ReflectanceToIris.vue";
|
||||
import Help from "./components/menubox/help.vue";
|
||||
import Greet from "./components/Greet.vue";
|
||||
import EventBus from "./eventBus.js";
|
||||
import {$ref} from "vue3-json-editor/dist/vue3-json-editor.cjs.js";
|
||||
@ -31,6 +35,14 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (command.type=="info"){
|
||||
if (command.name=="help"){
|
||||
this.modaltitle="关于";
|
||||
this.modalcomponent=Help;
|
||||
this.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -67,6 +79,9 @@ export default {
|
||||
this.$refs.Commancompent.GetSenSorInfo();
|
||||
this.showModal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(command.name=="Weavelenth")
|
||||
{
|
||||
if (!this.isinAdvanceMode()) return;
|
||||
@ -76,6 +91,16 @@ export default {
|
||||
// this.$refs.Commancompent.GetSenSorInfo();
|
||||
this.showModal();
|
||||
}
|
||||
if(command.name=="Weavelenthcoeff")
|
||||
{
|
||||
if (!this.isinAdvanceMode()) return;
|
||||
this.modaltitle="设置波长";
|
||||
this.modalcomponent=setWavelenthCoeff
|
||||
await this.$nextTick();
|
||||
// this.$refs.Commancompent.GetSenSorInfo();
|
||||
this.showModal();
|
||||
}
|
||||
|
||||
if (command.name=="Calibrate")
|
||||
{
|
||||
if (!this.isinAdvanceMode()) return;
|
||||
@ -87,6 +112,28 @@ export default {
|
||||
|
||||
|
||||
}
|
||||
if (command.name=="CalibrateHH3")
|
||||
{
|
||||
if (!this.isinAdvanceMode()) return;
|
||||
this.modaltitle="能量定标";
|
||||
this.modalcomponent=setCalibrateHH3
|
||||
await this.$nextTick();
|
||||
// this.$refs.Commancompent.GetSenSorInfo();
|
||||
this.showModal();
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (command.type=="Tool")
|
||||
{
|
||||
if (command.name=="ReflectanceToIris")
|
||||
{
|
||||
this.modaltitle="反射率转iris";
|
||||
this.modalcomponent=ReflectanceToIris
|
||||
await this.$nextTick();
|
||||
this.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
if (command.type=="Work")
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {invoke} from "@tauri-apps/api/tauri";
|
||||
import CommanDeffine from "../serportdefine.js";
|
||||
import EventBus from "../../eventBus.js";
|
||||
|
||||
let dev_info={};
|
||||
async function Dev_Opt() {
|
||||
var Command={command:"start_opt"};
|
||||
let data={
|
||||
@ -29,7 +29,14 @@ async function Dev_Opt() {
|
||||
|
||||
}
|
||||
|
||||
async function Get_Data_from_dev(Datatype) {
|
||||
async function Set_Gain(gain)
|
||||
{
|
||||
//todo 增益设置
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function Get_Data_from_dev(Datatype,shuttertimes,avgnumber=1) {
|
||||
|
||||
let drection=Datatype;
|
||||
//获取数据 UPDN
|
||||
@ -67,6 +74,7 @@ async function Get_Data_from_dev(Datatype) {
|
||||
{
|
||||
message=await invoke("sendtoport_andgetreturn",data);
|
||||
}
|
||||
|
||||
return message.data
|
||||
}
|
||||
|
||||
@ -103,7 +111,7 @@ async function Get_Date_on_Derction(drection,shuttertimes,autoremovedark=false,
|
||||
}
|
||||
data.data.collect_times=avgnumber;
|
||||
let message=await invoke("sendtoport_andgetreturn",data);
|
||||
await EnsureNotWorking();
|
||||
await EnsureNotWorking(Number(shuttertimes)/2);
|
||||
|
||||
|
||||
//获取数据 UPDN
|
||||
@ -136,6 +144,7 @@ async function Get_Date_on_Derction(drection,shuttertimes,autoremovedark=false,
|
||||
{
|
||||
message=await invoke("sendtoport_andgetreturn",data);
|
||||
}
|
||||
message.data.data.length=dev_info.bandnum;
|
||||
return message.data
|
||||
}
|
||||
|
||||
@ -163,7 +172,7 @@ async function Get_Dark_Data(drection,shuttertimes,avgnumber=1) {
|
||||
|
||||
data.data.collect_times=Number(avgnumber);
|
||||
let message=await invoke("sendtoport_andgetreturn",data);
|
||||
await EnsureNotWorking();
|
||||
await EnsureNotWorking(Number(shuttertimes)/2);
|
||||
|
||||
//获取数据 UPDN
|
||||
data = {
|
||||
@ -220,7 +229,7 @@ async function Get_Flat_Data(drection,shuttertimes,avgnumber=1) {
|
||||
|
||||
data.data.collect_times=Number(avgnumber);
|
||||
let message=await invoke("sendtoport_andgetreturn",data);
|
||||
await EnsureNotWorking();
|
||||
await EnsureNotWorking(Number(shuttertimes)/2);
|
||||
|
||||
|
||||
|
||||
@ -271,6 +280,7 @@ async function Get_Device_Info() {
|
||||
return {error:"error"};
|
||||
}
|
||||
let json=JSON.parse(message.content);
|
||||
dev_info=json;
|
||||
return json;
|
||||
}
|
||||
|
||||
@ -285,7 +295,7 @@ async function Get_Device_Info() {
|
||||
|
||||
|
||||
|
||||
async function EnsureNotWorking(){
|
||||
async function EnsureNotWorking(waittime=1000){
|
||||
let data={
|
||||
data:{
|
||||
command:"get_caiji_state"
|
||||
@ -304,7 +314,7 @@ async function EnsureNotWorking(){
|
||||
info:ret.info
|
||||
}
|
||||
EventBus.emit('setprogressbar',dataforprocess);
|
||||
await delay(1000);
|
||||
await delay(waittime);
|
||||
message=await invoke("sendtoport_andgetreturn",data);
|
||||
|
||||
if (message.content=="g time no data retrun")
|
||||
@ -325,16 +335,34 @@ function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function Set_Dev_Type(Devtype)
|
||||
{
|
||||
let message=await invoke("setdevtype",{devtype:Devtype});
|
||||
return message;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async function Set_Weave_Coeff(specnumber,a0,a1,a2,a3){
|
||||
var Command={};
|
||||
Command.specnumber=Number(specnumber);
|
||||
Command.a0=Number(a0);
|
||||
Command.a1=Number(a1);
|
||||
Command.a2=Number(a2);
|
||||
Command.a3=Number(a3);
|
||||
|
||||
|
||||
|
||||
|
||||
await invoke("set_weave_coeff",Command);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
@ -343,7 +371,10 @@ export default {
|
||||
Get_Device_Info,
|
||||
Get_Dark_Data,
|
||||
Get_Flat_Data,
|
||||
Get_Data_from_dev
|
||||
Get_Data_from_dev,
|
||||
Set_Dev_Type,
|
||||
Set_Gain,
|
||||
Set_Weave_Coeff
|
||||
|
||||
|
||||
|
||||
|
||||
@ -5,11 +5,15 @@ import EventBus from "../eventBus.js";
|
||||
import SerialportMethod from "./SerialPort/SerialportMethod.js";
|
||||
import { tr } from "element-plus/es/locales.mjs";
|
||||
import { type } from "vue3-json-editor/dist/vue3-json-editor.cjs.js";
|
||||
let sensorinfo={};
|
||||
export default {
|
||||
|
||||
async onDevchange(){
|
||||
console.log(this.sensor_typeforset)
|
||||
|
||||
SerialportMethod.Set_Dev_Type(this.sensor_typeforset);
|
||||
this.saveconfig();
|
||||
|
||||
},
|
||||
|
||||
async onshuttimechange(time){
|
||||
@ -77,14 +81,21 @@ export default {
|
||||
}
|
||||
if (Command=="DC")
|
||||
{
|
||||
let r=true
|
||||
let has_shutter=false;
|
||||
if (typeof(this.Devinfo.has_shutter)!="undefined")
|
||||
{
|
||||
has_shutter=this.Devinfo.has_shutter;
|
||||
}
|
||||
|
||||
if (!has_shutter)
|
||||
{r= await confirm(' 请扣上遮光罩--》再点击确定');}
|
||||
|
||||
let r= await confirm(' 请扣上遮光罩--》再点击确定');
|
||||
if (r)
|
||||
{
|
||||
this.iscollecting=true;
|
||||
|
||||
let datatoshow=await SerialportMethod.Get_Dark_Data("UP",this.ShutterTime[0],this.caijiavgNumber);
|
||||
let datatoshow=await SerialportMethod.Get_Dark_Data("UP",this.ShutterTime[0],10);
|
||||
this.iscollecting=false;
|
||||
// this.showdataasup(datatoshow);
|
||||
this.GetoneData();
|
||||
@ -133,7 +144,7 @@ export default {
|
||||
|
||||
let that=this;
|
||||
var i=0;
|
||||
var aa=await invoke("getportnames");
|
||||
//var aa=await invoke("getportnames");
|
||||
invoke("getportnames").then((message) => {
|
||||
message.forEach(function (port) {
|
||||
console.log(port.path);
|
||||
@ -182,6 +193,7 @@ export default {
|
||||
btn.disabled = true;
|
||||
this.buttoncolor.opencombutton="success";
|
||||
EventBus.emit('showbox',{title:"设备",body:"打开串口成功"});
|
||||
this.$globalState.isDevOpen=true;
|
||||
}else
|
||||
{
|
||||
btn.disabled = false;
|
||||
@ -200,6 +212,8 @@ export default {
|
||||
btnn.disabled = true;
|
||||
alert(await invoke("closecome"));
|
||||
this.SerialInfo.isopen=false;
|
||||
this.$globalState.isDevOpen=false;
|
||||
|
||||
|
||||
|
||||
},
|
||||
@ -295,6 +309,7 @@ export default {
|
||||
|
||||
|
||||
let datatoshow=await SerialportMethod.Get_Date_on_Derction(drection,shuttertimes,this.autoremovedark,avgnumber);
|
||||
|
||||
if (this.dataprocessconfig.useSG)
|
||||
{
|
||||
datatoshow.data= await invoke("sg_smooth",{data:datatoshow.data,window:31,order:7});
|
||||
@ -423,6 +438,7 @@ export default {
|
||||
let coeffweave2=this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3=this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4=this.Devinfo.bochangxishu.a3;
|
||||
let bandnum=this.Devinfo.bandnum;
|
||||
//获取数据 UPDN
|
||||
data = {
|
||||
data: {
|
||||
@ -441,10 +457,11 @@ export default {
|
||||
this.dataup=datatoshowup;
|
||||
let lenthofdataup=datatoshowup.data.length;
|
||||
let dataforshowup=[];
|
||||
|
||||
for (var i=0;i<lenthofdataup;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
dataforshowup.push([weave,datatoshowup.data[2048-i-1]]);
|
||||
dataforshowup.push([weave,datatoshowup.data[bandnum-i-1]]);
|
||||
}
|
||||
this.datainfoup.infolist=[];
|
||||
this.datainfoup.hasrecive=true;
|
||||
@ -482,7 +499,7 @@ export default {
|
||||
for (var i=0;i<lenthofdatadown;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
dataforshowdown.push([weave,datatoshowdown.data[2048-i-1]]);
|
||||
dataforshowdown.push([weave,datatoshowdown.data[bandnum-i-1]]);
|
||||
}
|
||||
this.datainfodown.hasrecive=true;
|
||||
this.datainfodown.infolist=[];
|
||||
@ -528,22 +545,29 @@ export default {
|
||||
datatype:"json"
|
||||
}
|
||||
let that = this;
|
||||
let message=await invoke("sendtoport_andgetreturn",data);
|
||||
if (message.datatype==108)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let json=JSON.parse(message.content);
|
||||
// let message=await invoke("sendtoport_andgetreturn",data);
|
||||
// if (message.datatype==108)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// let json=JSON.parse(message.content);
|
||||
let json = await SerialportMethod.Get_Device_Info();
|
||||
this.Devinfo=json;
|
||||
if (typeof(this.Devinfo.sensor_type)==undefined)
|
||||
let aaa=typeof(this.Devinfo.sensor_type);
|
||||
if (aaa=="undefined")
|
||||
{
|
||||
this.Devinfo.sensor_type="IRIS-IS11";
|
||||
this.Devinfo.fiber_type="Dual";
|
||||
}
|
||||
|
||||
if (this.Devinfo.sensor_type=="JZ-IS11")
|
||||
if (this.Devinfo.sensor_type=="IRIS-Sensor")
|
||||
{
|
||||
this.UPStr="DN"
|
||||
EventBus.emit('setplotname',{up:"DN"});
|
||||
if(typeof(this.Devinfo.fiber_type)=="undefined")
|
||||
{
|
||||
this.Devinfo.fiber_type="Single";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -558,9 +582,10 @@ export default {
|
||||
let coeffweave2=this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3=this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4=this.Devinfo.bochangxishu.a3;
|
||||
let BANDNUM=this.Devinfo.bandnum;
|
||||
var wevaconfig={
|
||||
min:coeffweave1*0*0*0+coeffweave2*0*0+coeffweave3*0+coeffweave4,
|
||||
max:coeffweave1*2048*2048*2048+coeffweave2*2048*2048+coeffweave3*2048+coeffweave4
|
||||
max:coeffweave1*(BANDNUM-1)*(BANDNUM-1)*(BANDNUM-1)+coeffweave2*(BANDNUM-1)*(BANDNUM-1)+coeffweave3*(BANDNUM-1)+coeffweave4
|
||||
|
||||
}
|
||||
EventBus.emit('plotsetwavelength',wevaconfig);
|
||||
|
||||
@ -49,9 +49,22 @@ export default {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener("keydown",this.handlekeydown)
|
||||
// 仅在挂载时注册总线,不在这里绑定全局键盘事件(避免 KeepAlive 导致的重复/遗留绑定)
|
||||
EventBus.on('SetMenubutton',this.setbutton);
|
||||
},
|
||||
activated() {
|
||||
// 仅在当前页面处于激活状态时绑定
|
||||
window.addEventListener("keydown", this.handlekeydown);
|
||||
},
|
||||
deactivated() {
|
||||
// 从可见切换为缓存(隐藏)时,解绑,避免隐藏页误触发
|
||||
window.removeEventListener("keydown", this.handlekeydown);
|
||||
},
|
||||
beforeUnmount() {
|
||||
// 彻底卸载时,兜底解绑
|
||||
window.removeEventListener("keydown", this.handlekeydown);
|
||||
EventBus.off && EventBus.off('SetMenubutton', this.setbutton);
|
||||
},
|
||||
methods: {
|
||||
setbutton(command){
|
||||
if (command.name == "DC"){
|
||||
@ -66,6 +79,9 @@ export default {
|
||||
showbox(){
|
||||
EventBus.emit('showbox',"hello","提示11")
|
||||
},
|
||||
changemainvue() {
|
||||
EventBus.emit('changemainvue');
|
||||
},
|
||||
|
||||
onmenuclick(type, name) {
|
||||
|
||||
@ -80,7 +96,21 @@ export default {
|
||||
this.$emit("menubalclicked", command)
|
||||
},
|
||||
handlekeydown(event) {
|
||||
// console.log(event.key);
|
||||
// 在可编辑环境中不触发应用快捷键
|
||||
const t = event.target || {};
|
||||
const tag = (t.tagName || '').toLowerCase();
|
||||
const isEditable = t.isContentEditable || tag === 'input' || tag === 'textarea' || tag === 'select';
|
||||
if (isEditable) return;
|
||||
|
||||
// 只处理来自本应用根节点(#app)内的事件,忽略外部悬浮窗/插件
|
||||
const appRoot = document.getElementById('app');
|
||||
if (!appRoot || !appRoot.contains(event.target)) return;
|
||||
|
||||
// 不劫持系统复制快捷键 Ctrl+C
|
||||
if (event.ctrlKey && !event.shiftKey && (event.key === 'c' || event.key === 'C')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.ctrlKey) {
|
||||
if (event.key == "n" || event.key == "N") {
|
||||
this.onmenuclick('Set', 'Workmode');
|
||||
@ -91,11 +121,10 @@ export default {
|
||||
if (event.key == "w" || event.key == "W") {
|
||||
this.onmenuclick('Set', 'Weavelenth');
|
||||
}
|
||||
if (event.key == "c" || event.key == "C") {
|
||||
// 将“定标”快捷键改为 Ctrl + Shift + C,避免与系统复制冲突
|
||||
if (event.shiftKey && (event.key == "c" || event.key == "C")) {
|
||||
this.onmenuclick('Set', 'Calibrate');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,26 +155,33 @@ export default {
|
||||
<BDropdownDivider></BDropdownDivider>
|
||||
<BDropdownItem href="#">退出</BDropdownItem>
|
||||
<BDropdownItem href="#" @click="onmenuclick('File','Advance')">高级</BDropdownItem>
|
||||
|
||||
<BDropdownItem @click="onmenuclick('info','help')">帮助</BDropdownItem>
|
||||
</BNavItemDropdown>
|
||||
|
||||
<!-- <!– Navbar dropdowns –>-->
|
||||
<BNavItemDropdown text="窗口" right>
|
||||
|
||||
<!-- <BDropdownItem @click="showbox">EN</BDropdownItem>-->
|
||||
<!-- <BDropdownItem >ES</BDropdownItem>-->
|
||||
<!-- <BDropdownItem href="#">RU</BDropdownItem>-->
|
||||
<!-- <BDropdownItem href="#">FA</BDropdownItem>-->
|
||||
</BNavItemDropdown>
|
||||
|
||||
<BNavItemDropdown text="设置" right>
|
||||
<BDropdownItem @click="onmenuclick('Set','Workmode')">工作模式</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','DevInfo')">设备信息</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','Weavelenth')">波长系数</BDropdownItem>
|
||||
<!-- <BDropdownItem @click="onmenuclick('Set','Weavelenth')">波长系数</BDropdownItem> -->
|
||||
<BDropdownItem @click="onmenuclick('Set','Weavelenthcoeff')">波长设定</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','Calibrate')">定标</BDropdownItem>
|
||||
<BDropdownItem @click="onmenuclick('Set','CalibrateHH3')">HH3定标</BDropdownItem>
|
||||
</BNavItemDropdown>
|
||||
|
||||
<BNavItemDropdown text="工具" right>
|
||||
<BDropdownItem @click="onmenuclick('Tool','ReflectanceToIris')">反射率转iris</BDropdownItem>
|
||||
</BNavItemDropdown>
|
||||
|
||||
<BNavItemDropdown text="窗口" right>
|
||||
|
||||
|
||||
<BDropdownItem @click="changemainvue()">数据查看</BDropdownItem>
|
||||
<!-- <BDropdownItem >ES</BDropdownItem>-->
|
||||
<!-- <BDropdownItem href="#">RU</BDropdownItem>-->
|
||||
<!-- <BDropdownItem href="#">FA</BDropdownItem>-->
|
||||
</BNavItemDropdown>
|
||||
|
||||
|
||||
|
||||
|
||||
1112
src/components/menubox/SetCalibrateHH3.vue
Normal file
640
src/components/menubox/SetCalibrateback.vue
Normal file
@ -0,0 +1,640 @@
|
||||
<script>
|
||||
|
||||
import SerialportMethod from "../SerialPort/SerialportMethod.js";
|
||||
import * as echarts from "echarts";
|
||||
import EventBus from "../../eventBus.js";
|
||||
import {dialog, fs} from "@tauri-apps/api";
|
||||
import {invoke} from "@tauri-apps/api/tauri";
|
||||
import SerilporDefine from "../serportdefine.js";
|
||||
export default {
|
||||
name: "SetCalibrate",
|
||||
data(){
|
||||
return {
|
||||
shutter_time_up:1,
|
||||
shutter_time_down:1,
|
||||
option_up:{},
|
||||
option_down:{},
|
||||
option_lamp:{},
|
||||
Devinfo:{
|
||||
work_mode:0,
|
||||
},
|
||||
DataUP:{shutter_time:0,value_lable:0},
|
||||
DataDown:{shutter_time:0,value_lable:0},
|
||||
LampData:{value_lable:0},
|
||||
caijicishu:[1,1],
|
||||
upGain:{gain:[],shutter_time:0},
|
||||
downGain:{gain:[],shutter_time:0},
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//100ms 后执行
|
||||
setTimeout(() => {
|
||||
this.initChart();
|
||||
}, 100);
|
||||
// setTimeout(() => {
|
||||
// this.readFileAndParse()
|
||||
// }, 1000);
|
||||
|
||||
// this.initChart();
|
||||
},
|
||||
methods: {
|
||||
|
||||
updateCalifile(){
|
||||
let aa=invoke("sendcalibratetodev",{
|
||||
gain:this.upGain.gain,
|
||||
shutter:this.upGain.shutter_time,
|
||||
direction:SerilporDefine.Derection.Up
|
||||
});
|
||||
console.log(aa);
|
||||
let aa1=invoke("sendcalibratetodev",{
|
||||
gain:this.downGain.gain,
|
||||
shutter:this.downGain.shutter_time,
|
||||
direction:SerilporDefine.Derection.Down
|
||||
});
|
||||
console.log(aa1);
|
||||
},
|
||||
async readFileAndParse() {
|
||||
|
||||
var options= {
|
||||
defaultPath: "../",
|
||||
directory: false,
|
||||
title: "请选择保存路径",
|
||||
}
|
||||
var pathofdir=await dialog.open(options);
|
||||
|
||||
try {
|
||||
// 读取文件内容
|
||||
const data = await fs.readTextFile(pathofdir);
|
||||
|
||||
// 解析文件内容
|
||||
const lines = data.split('\n');
|
||||
const valueLine = lines.shift(); // 读取第一行
|
||||
const [key, value] = valueLine.split('='); // 解析第一行内容
|
||||
const valueVar = parseFloat(value); // 将 value 转换为数字
|
||||
|
||||
const weaveValues = [];
|
||||
const valueValues = [];
|
||||
|
||||
// 解析剩余行的内容
|
||||
for (const line of lines) {
|
||||
if (line.trim() !== '') { // 排除空行
|
||||
const [weave, val] = line.split(' ').map(Number); // 将每一行的两个值转换为数字
|
||||
weaveValues.push(weave*1000);
|
||||
valueValues.push(val);
|
||||
}
|
||||
}
|
||||
let coeffweave1=this.Devinfo.bochangxishu.a0;
|
||||
let coeffweave2=this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3=this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4=this.Devinfo.bochangxishu.a3;
|
||||
let lenthofdata=this.Devinfo.bandnum;
|
||||
let weavetarget=[];
|
||||
for (var i=0;i<lenthofdata;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
weavetarget.push(weave);
|
||||
|
||||
}
|
||||
let valuetarget= await invoke("interpolate_spline_at_points",{
|
||||
x:weaveValues,
|
||||
y:valueValues,
|
||||
xTarget:weavetarget
|
||||
});
|
||||
// console.log(valuetarget);
|
||||
this.LampData={weave:weavetarget,value:valuetarget,value_lable:valueVar};
|
||||
var dataforshow=[];
|
||||
for (var i=0;i<lenthofdata;i++)
|
||||
{
|
||||
dataforshow.push([weavetarget[i],valuetarget[i]]);
|
||||
}
|
||||
var char_lamp=echarts.getInstanceByDom(this.$refs.chart_lamp);
|
||||
this.option_lamp.series[0].data=dataforshow;
|
||||
char_lamp.setOption(this.option_lamp);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error reading file:', err);
|
||||
}
|
||||
},
|
||||
async OPT_devic(dire) {
|
||||
var shuttertime = await SerialportMethod.Dev_Opt();
|
||||
if (dire == 0) this.shutter_time_up = shuttertime;
|
||||
else this.shutter_time_down = shuttertime;
|
||||
|
||||
},
|
||||
async initChart() {
|
||||
this.Devinfo= await SerialportMethod.Get_Device_Info();
|
||||
var coeff=[];
|
||||
coeff[0]=this.Devinfo.bochangxishu.a0;
|
||||
coeff[1]=this.Devinfo.bochangxishu.a1;
|
||||
coeff[2]=this.Devinfo.bochangxishu.a2;
|
||||
coeff[3]=this.Devinfo.bochangxishu.a3;
|
||||
let bandnum=this.Devinfo.bandnum;
|
||||
const chartDom_up = this.$refs.chart_up;
|
||||
let chart_up = echarts.init(chartDom_up, null, {renderer: 'svg'});
|
||||
let chart_down = echarts.init(this.$refs.chart_down, null, {renderer: 'svg'});
|
||||
let chart_lamp = echarts.init(this.$refs.chart_lamp, null, {renderer: 'svg'});
|
||||
chart_up.resize();
|
||||
chart_down.resize();
|
||||
chart_lamp.resize();
|
||||
this.option_up = {
|
||||
|
||||
|
||||
// ECharts 配置选项
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: false,// 显示连续的刻度
|
||||
min: 0,
|
||||
max: 1100,
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside', // 内置数据区域缩放
|
||||
start: 0, // 初始缩放范围的起始位置(0%)
|
||||
end: 100 // 初始缩放范围的结束位置(100%)
|
||||
}
|
||||
],
|
||||
triggerEvent: true
|
||||
},
|
||||
animation: false,
|
||||
yAxis:[ {
|
||||
type: 'value',
|
||||
//min:0,
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
//min:0,
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
|
||||
|
||||
},
|
||||
axisPointer: {
|
||||
link: {xAxisIndex: 'all'},
|
||||
label: {
|
||||
backgroundColor: '#777'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '10%',
|
||||
top: '5%'
|
||||
},
|
||||
// visualMap: [
|
||||
// {
|
||||
// type: 'continuous',
|
||||
// }
|
||||
// ],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside', // 内置数据区域缩放,包括滚轮缩放
|
||||
xAxisIndex: [0], // 对应 x 轴
|
||||
filterMode: 'none' // 不过滤数据
|
||||
|
||||
},
|
||||
{
|
||||
type: 'inside', // 内置数据区域缩放,包括滚轮缩放
|
||||
yAxisIndex: [0], // 对应 y 轴
|
||||
filterMode: 'none', // 不过滤数据
|
||||
//width :15
|
||||
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
legend: {
|
||||
data: ['DN'], // 图例名称
|
||||
show: true ,// 显示图例
|
||||
//selectedMode: 'multiple', // 图例的选择模式。默认开启图例开关,可选single,multiple
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [[1, 150], [2, 230], [3, 224], [4, 218], [5, 135], [6, 147], [7, 260]], // 使用二维数组表示数据点的坐标
|
||||
type: 'line',
|
||||
name: 'DN',
|
||||
symbol: 'none', // 不显示数据点
|
||||
smooth: false, // 不使用平滑处理
|
||||
// step: 'start' // 设置 step 类型的起始位置
|
||||
}
|
||||
// ,
|
||||
// {
|
||||
// data: [[1, 150], [2, 230], [3, 224], [4, 218], [5, 135], [6, 147], [7, 260]], // 使用二维数组表示数据点的坐标
|
||||
// type: 'line',
|
||||
// name: 'data',
|
||||
// symbol: 'none', // 不显示数据点
|
||||
// smooth: false, // 不使用平滑处理
|
||||
// yAxisIndex: 1,
|
||||
// // step: 'start' // 设置 step 类型的起始位置
|
||||
// }
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
this.option_up.xAxis.max =coeff[3];
|
||||
bandnum=bandnum-1;
|
||||
this.option_up.xAxis.min = bandnum*bandnum*bandnum*coeff[0]+bandnum*bandnum*coeff[1]+bandnum*coeff[2]+coeff[3];
|
||||
this.option_lamp = JSON.parse(JSON.stringify(this.option_up));
|
||||
this.option_down = JSON.parse(JSON.stringify(this.option_up));
|
||||
|
||||
chart_up.setOption(this.option_up);
|
||||
chart_down.setOption(this.option_down);
|
||||
this.option_lamp.legend.data = ['Lamp'];
|
||||
this.option_lamp.series[0].name = 'Lamp';
|
||||
chart_lamp.setOption(this.option_lamp);
|
||||
|
||||
|
||||
},
|
||||
async Get_Data_direction(dire) {
|
||||
let coeffweave1=this.Devinfo.bochangxishu.a0;
|
||||
let coeffweave2=this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3=this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4=this.Devinfo.bochangxishu.a3;
|
||||
if (dire == "UP") {
|
||||
var data = await SerialportMethod.Get_Date_on_Derction(dire,this.shutter_time_up,true,Number(this.caijicishu[0]))
|
||||
this.DataUP=data;
|
||||
this.DataUP.value_lable=0
|
||||
//获取波长系数
|
||||
var lenthofdata=data.data.length;
|
||||
let dataforshow=[];
|
||||
for (var i=0;i<lenthofdata;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
dataforshow.push([weave,data.data[i]]);
|
||||
}
|
||||
this.option_up.series[0].data = dataforshow;
|
||||
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_up);
|
||||
chart_up.setOption(this.option_up);
|
||||
|
||||
// console.log(dataforshow);
|
||||
}else if(dire=="DOWN")
|
||||
{
|
||||
var data = await SerialportMethod.Get_Date_on_Derction(dire,this.shutter_time_down,true,Number(this.caijicishu[0]))
|
||||
this.DataDown=data;
|
||||
this.DataDown.value_lable=0
|
||||
//获取波长系数
|
||||
var lenthofdata=data.data.length;
|
||||
let dataforshow=[];
|
||||
for (var i=0;i<lenthofdata;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
dataforshow.push([weave,data.data[i]]);
|
||||
}
|
||||
this.option_down.series[0].data = dataforshow;
|
||||
|
||||
var chart_down = echarts.getInstanceByDom(this.$refs.chart_down);
|
||||
chart_down.setOption(this.option_down);
|
||||
|
||||
// console.log(dataforshow);
|
||||
}
|
||||
this.computCalibrate()
|
||||
},
|
||||
async computCalibrate(){
|
||||
|
||||
if(this.upGain.shutter_time!=0)
|
||||
{
|
||||
let coeffweave1=this.Devinfo.bochangxishu.a0;
|
||||
let coeffweave2=this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3=this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4=this.Devinfo.bochangxishu.a3;
|
||||
var uprandiance=[];
|
||||
if(this.DataUP.data.length!=0)
|
||||
{
|
||||
for (var i=0;i<this.DataUP.data.length;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
var data=this.DataUP.data[i]*this.upGain.gain[i]*this.upGain.shutter_time/this.DataUP.shutter_time;
|
||||
uprandiance.push([weave,data]);
|
||||
}
|
||||
var series=
|
||||
{
|
||||
data: [[1, 150], [2, 230], [3, 224], [4, 218], [5, 135], [6, 147], [7, 260]], // 使用二维数组表示数据点的坐标
|
||||
type: 'line',
|
||||
name: 'Radiance',
|
||||
symbol: 'none', // 不显示数据点
|
||||
smooth: false, // 不使用平滑处理
|
||||
yAxisIndex: 1,
|
||||
// step: 'start' // 设置 step 类型的起始位置
|
||||
}
|
||||
series.data=uprandiance;
|
||||
if(this.option_up.series.length==1)
|
||||
{
|
||||
this.option_up.series.push(series);
|
||||
this.option_up.legend.data.push('Radiance');
|
||||
}else{
|
||||
this.option_up.series[1]=series;
|
||||
}
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_up);
|
||||
chart_up.setOption(this.option_up);
|
||||
//this.option_up.series
|
||||
}
|
||||
}
|
||||
if(this.downGain.shutter_time!=0)
|
||||
{
|
||||
let coeffweave1=this.Devinfo.bochangxishu.a0;
|
||||
let coeffweave2=this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3=this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4=this.Devinfo.bochangxishu.a3;
|
||||
var downrandiance=[];
|
||||
if(this.DataDown.data.length!=0)
|
||||
{
|
||||
for (var i=0;i<this.DataDown.data.length;i++)
|
||||
{
|
||||
var weave=coeffweave1*i*i*i+coeffweave2*i*i+coeffweave3*i+coeffweave4;
|
||||
var data=this.DataDown.data[i]*this.downGain.gain[i]*this.upGain.shutter_time/this.DataDown.shutter_time;
|
||||
downrandiance.push([weave,data]);
|
||||
}
|
||||
var series=
|
||||
{
|
||||
data: [[1, 150], [2, 230], [3, 224], [4, 218], [5, 135], [6, 147], [7, 260]], // 使用二维数组表示数据点的坐标
|
||||
type: 'line',
|
||||
name: 'Radiance',
|
||||
symbol: 'none', // 不显示数据点
|
||||
smooth: false, // 不使用平滑处理
|
||||
yAxisIndex: 1,
|
||||
// step: 'start' // 设置 step 类型的起始位置
|
||||
}
|
||||
series.data=downrandiance;
|
||||
if(this.option_down.series.length==1)
|
||||
{
|
||||
this.option_down.series.push(series);
|
||||
this.option_down.legend.data.push('Radiance');
|
||||
}else{
|
||||
this.option_down.series[1]=series;
|
||||
}
|
||||
var chart_down = echarts.getInstanceByDom(this.$refs.chart_down);
|
||||
chart_down.setOption(this.option_down);
|
||||
//this.option_up.series
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
async SaveGaindata(){
|
||||
if(this.upGain.shutter_time!=0)
|
||||
{
|
||||
console.log(this.upGain.gain);
|
||||
let data={
|
||||
gain:this.upGain.gain,
|
||||
shutter:this.upGain.shutter_time,
|
||||
direction:true,
|
||||
filepath:"./calibratefile/upgain.bin"
|
||||
}
|
||||
await invoke("savecalibratefile",data);
|
||||
// await invoke("sendcalibratetodev",{
|
||||
// gain:this.upGain.gain,
|
||||
// shutter:this.upGain.shutter_time,
|
||||
// direction:true
|
||||
|
||||
// });
|
||||
}
|
||||
|
||||
if(this.downGain.shutter_time!=0)
|
||||
{
|
||||
await invoke("savecalibratefile",{
|
||||
gain:this.downGain.gain,
|
||||
shutter:this.downGain.shutter_time,
|
||||
direction:true,
|
||||
filepath:"./calibratefile/downgain.bin"
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
async Start_Comput_Coeff(){
|
||||
let lampData=this.LampData.value;
|
||||
let lampLabel=this.LampData.value_lable;
|
||||
let UpData=this.DataUP.data;
|
||||
let UpLabel=this.DataUP.value_lable;
|
||||
let UpShutter=this.DataUP.shutter_time;
|
||||
let DownData=this.DataDown.data;
|
||||
let DownLabel=this.DataDown.value_lable;
|
||||
let DownShutter=this.DataDown.shutter_time;
|
||||
if (lampLabel==0)
|
||||
{
|
||||
alert("请先导入灯数据");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DownShutter==0||UpShutter==0)
|
||||
{
|
||||
alert("请先采集数据");
|
||||
return;
|
||||
}
|
||||
if (UpLabel==0||DownLabel==0)
|
||||
{
|
||||
alert("请填写对应的Value");
|
||||
return;
|
||||
}
|
||||
|
||||
let gainofup=[];
|
||||
let gainofdown=[];
|
||||
for (var i=0;i<UpData.length;i++)
|
||||
{
|
||||
let upDn=UpData[i];
|
||||
let downDn=DownData[i];
|
||||
let lampup=lampData[i]*UpLabel/lampLabel;
|
||||
let lampdown=lampData[i]*DownLabel/lampLabel;
|
||||
let gainup=lampup/upDn;
|
||||
//判断upDN是否为0 如果是0 则gainup为前一个值 如果是第一个 则为1
|
||||
|
||||
if (upDn==0)
|
||||
{
|
||||
if (i==0)
|
||||
{
|
||||
gainup=1;
|
||||
}else{
|
||||
gainup=gainofup[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
let gaindown=lampdown/downDn;
|
||||
//判断downDn是否为0 如果是0 则gainup为前一个值 如果是第一个 则为1
|
||||
if (downDn==0)
|
||||
{
|
||||
if (i==0)
|
||||
{
|
||||
gaindown=1;
|
||||
}else{
|
||||
gaindown=gainofdown[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gainofup.push(gainup);
|
||||
gainofdown.push(gaindown);
|
||||
}
|
||||
this.upGain.gain=gainofup;
|
||||
this.upGain.shutter_time=UpShutter;
|
||||
this.downGain.gain=gainofdown;
|
||||
this.downGain.shutter_time=DownShutter;
|
||||
this.computCalibrate()
|
||||
this.SaveGaindata();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container" style="width: 100%;height: 100%;max-width:100%;margin: 0px;padding: 0px">
|
||||
<div class="row linebox">
|
||||
<!-- 按钮区域-->
|
||||
<div class="col-2 buttonme">
|
||||
<b-button variant="secondary" pill class="siglebt" @click="readFileAndParse()">导入灯数据</b-button>
|
||||
</div>
|
||||
<!-- ///中间区域-->
|
||||
<div class="col-9 centerme">
|
||||
<div class="chart-container" id="charmian_lamp" ref="chart_lamp" ></div>
|
||||
</div>
|
||||
<!-- ///尾部区域-->
|
||||
<div class="col-1 tailme">
|
||||
<b-form-floating-label style="margin: auto" v-show="LampData.value_lable!==0">value:{{LampData.value_lable}}</b-form-floating-label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 中建行 -->
|
||||
<div class="row linebox">
|
||||
|
||||
<!-- 按钮区域-->
|
||||
<div class="col-2 buttonme" style="padding: 0px" size="sm">
|
||||
<b-input-group append="ms">
|
||||
<b-input-group-prepend>
|
||||
<b-button variant="secondary" style="margin: auto" @click="OPT_devic(0)">OPT</b-button>
|
||||
</b-input-group-prepend>
|
||||
<b-form-input v-model="shutter_time_up"></b-form-input>
|
||||
|
||||
|
||||
</b-input-group>
|
||||
<b-input-group append="次">
|
||||
<b-input-group-prepend>
|
||||
<b-button variant="secondary" style="margin: auto" @click="Get_Data_direction('UP')">采集向上数据</b-button>
|
||||
</b-input-group-prepend>
|
||||
<b-form-input v-model="caijicishu[0]"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
</div>
|
||||
<!-- ///中间区域-->
|
||||
<div class="col-9 centerme">
|
||||
<div class="chart-container" id="charmian_up" ref="chart_up" ></div>
|
||||
</div>
|
||||
<!-- ///尾部区域-->
|
||||
<div class="col-1 tailme">
|
||||
<b-form-floating-label style="margin: auto" v-show="DataUP.shutter_time!==0">Shutter_Time:{{DataUP.shutter_time}}</b-form-floating-label>
|
||||
<b-input-group prepend="Lamp_Value" size="sm" v-show="DataUP.shutter_time!==0">
|
||||
</b-input-group>
|
||||
<b-form-input v-model="DataUP.value_lable"></b-form-input>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- 向下 -->
|
||||
<div class="row linebox">
|
||||
<!-- 按钮区域-->
|
||||
<div class="col-2 buttonme">
|
||||
<b-input-group append="ms">
|
||||
<b-input-group-prepend>
|
||||
<b-button variant="secondary" style="margin: auto" @click="OPT_devic(1)"> OPT</b-button>
|
||||
</b-input-group-prepend>
|
||||
<b-form-input v-model="shutter_time_down"></b-form-input>
|
||||
|
||||
|
||||
</b-input-group>
|
||||
<b-input-group append="次">
|
||||
<b-input-group-prepend>
|
||||
<b-button variant="secondary" @click="Get_Data_direction('DOWN')">采集向下数据</b-button>
|
||||
</b-input-group-prepend>
|
||||
<b-form-input v-model="caijicishu[1]"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
</div>
|
||||
<!-- ///中间区域-->
|
||||
<div class="col-9 centerme">
|
||||
<div class="chart-container" id="charmian_up" ref="chart_down" ></div>
|
||||
</div>
|
||||
<!-- ///尾部区域-->
|
||||
<div class="col-1 tailme">
|
||||
<b-form-floating-label style="margin: auto" v-show="DataDown.shutter_time!==0">Shutter_Time:{{DataDown.shutter_time}}</b-form-floating-label>
|
||||
<b-input-group prepend="Lamp_Value" size="sm" v-show="DataDown.shutter_time!==0">
|
||||
</b-input-group>
|
||||
<b-form-input v-model="DataDown.value_lable"></b-form-input>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<p style="position:absolute ;bottom: 10px;width: 100%;height: 30px" >
|
||||
<b-button @click="updataName" style="position:absolute;left: 20px ">导入已有文件</b-button>
|
||||
<b-button @click="Start_Comput_Coeff()" style="position:absolute; left: 150px ">计算</b-button>
|
||||
<b style="position:absolute; left: 250px;border: #0f0f0f 1px solid; margin: auto">adsfsdsadfsdf</b>
|
||||
<b-button @click="updateCalifile" style="position:absolute;right: 20px ">设置</b-button>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.linebox{
|
||||
width: 100%;
|
||||
height: 30%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border-bottom:1px solid #d2dede;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.buttonme{
|
||||
background-color: #f8f9fa;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding: 0px;
|
||||
border-right: 1px solid #d2dede;
|
||||
align-content: center;
|
||||
|
||||
}
|
||||
.centerme{
|
||||
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding: 0px;
|
||||
border-right: 1px solid #d2dede;
|
||||
}
|
||||
.tailme{
|
||||
background-color: #f8f9fa;
|
||||
margin: auto;
|
||||
|
||||
}
|
||||
.chart-container{
|
||||
width: 100%;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -123,9 +123,10 @@ export default {
|
||||
}
|
||||
]
|
||||
};
|
||||
let bandnum=this.Devinfo.bandnum-1;
|
||||
this.option.xAxis.max =coeff[3];
|
||||
|
||||
this.option.xAxis.min = 2048*2048*2048*coeff[0]+2048*2048*coeff[1]+2048*coeff[2]+coeff[3];
|
||||
this.option.xAxis.min = bandnum*bandnum*bandnum*coeff[0]+bandnum*bandnum*coeff[1]+bandnum*coeff[2]+coeff[3];
|
||||
|
||||
chart.setOption(this.option);
|
||||
chart.dispatchAction({
|
||||
|
||||
915
src/components/menubox/SetWavelenthcoeff.vue
Normal file
@ -0,0 +1,915 @@
|
||||
<script>
|
||||
import { invoke } from "@tauri-apps/api/tauri";
|
||||
import * as echarts from "echarts";
|
||||
import SensorMethod from "../SerialPort/SerialportMethod.js";
|
||||
import { Checkbox } from "@arco-design/web-vue";
|
||||
export default {
|
||||
name: "SetWavelenth",
|
||||
data() {
|
||||
return {
|
||||
option: {},
|
||||
optiondown: {},
|
||||
Devinfo: {
|
||||
work_mode: 0,
|
||||
bochangxishu: {
|
||||
a0: 0,
|
||||
a1: 0,
|
||||
a2: 0,
|
||||
a3: 0
|
||||
},
|
||||
bochangxishu2: {
|
||||
a0: 0,
|
||||
a1: 0,
|
||||
a2: 0,
|
||||
a3: 0
|
||||
},
|
||||
fiber_type: "Dual"
|
||||
|
||||
|
||||
},
|
||||
WeavePeaksDeffine: [
|
||||
0,
|
||||
253.652,
|
||||
296.728,
|
||||
302.150,
|
||||
313.155,
|
||||
334.148,
|
||||
365.015,
|
||||
404.656,
|
||||
407.783,
|
||||
435.833,
|
||||
546.074,
|
||||
576.960,
|
||||
579.066,
|
||||
587.092,
|
||||
696.543,
|
||||
706.722,
|
||||
714.704,
|
||||
727.294,
|
||||
738.393,
|
||||
750.387,
|
||||
763.511,
|
||||
772.376,
|
||||
785.482,
|
||||
794.818,
|
||||
800.616,
|
||||
811.531,
|
||||
826.452,
|
||||
842.465,
|
||||
850.887,
|
||||
852.144,
|
||||
866.794,
|
||||
892.869,
|
||||
912.297,
|
||||
922.450,
|
||||
965.779,
|
||||
1013.976
|
||||
],
|
||||
shutter_time_up: 1,
|
||||
shutter_time_down: 1,
|
||||
sensor_gain_up: 0,
|
||||
sensor_gain_down: 0,
|
||||
Data: {},
|
||||
DataDown: {},
|
||||
Peaks: [],
|
||||
PeaksDown: []
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
let that = this;
|
||||
//await
|
||||
await setTimeout(function () {
|
||||
that.GetSenSorInfo();
|
||||
// 这里是你要在100毫秒后执行的代码
|
||||
|
||||
}, 100);
|
||||
await setTimeout(function () {
|
||||
that.GetSenSorInfo();
|
||||
// 这里是你要在100毫秒后执行的代码
|
||||
that.initChart();
|
||||
}, 1000);
|
||||
|
||||
},
|
||||
unmounted() {
|
||||
window.removeEventListener('resize', this.echartresize);
|
||||
},
|
||||
|
||||
methods: {
|
||||
async GetSenSorInfo() {
|
||||
// var Command = { command: "get_sensor_info" };
|
||||
// let data = {
|
||||
// data: Command,
|
||||
// datatype: "json"
|
||||
// }
|
||||
// let message = await invoke("sendtoport_andgetreturn", data);
|
||||
this.Devinfo = await SensorMethod.Get_Device_Info();
|
||||
this.sensor_gain_down = this.Devinfo.sensor_gain_down;
|
||||
if (typeof (this.Devinfo.fiber_type) == "string") {
|
||||
this.fiber_type = this.Devinfo.fiber_type;
|
||||
}
|
||||
if (this.Devinfo.fiber_type == "Single") {
|
||||
this.shutter_time_up = this.Devinfo.shutter_time;
|
||||
} else if (this.Devinfo.fiber_type == "Dual") {
|
||||
this.sensor_gain_up = this.Devinfo.sensor_gain_up;
|
||||
this.shutter_time_down = this.Devinfo.shutter_time_down;
|
||||
this.shutter_time_up = this.Devinfo.shutter_time_up;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
async OPT_devic() {
|
||||
var shuttertime = await SensorMethod.Dev_Opt();
|
||||
this.shutter_time_up = shuttertime;
|
||||
|
||||
},
|
||||
async initChart() {
|
||||
await this.$nextTick();
|
||||
const chartDom = this.$refs.chart_weavelenth;
|
||||
// chartDom.style.width = '100%';
|
||||
// chartDom.style.height = '100%';
|
||||
let height = chartDom.offsetHeight;
|
||||
let width = chartDom.clientWidth;
|
||||
let chart = echarts.init(chartDom);
|
||||
|
||||
|
||||
var coeff = [];
|
||||
coeff[0] = this.Devinfo.bochangxishu.a0;
|
||||
coeff[1] = this.Devinfo.bochangxishu.a1;
|
||||
coeff[2] = this.Devinfo.bochangxishu.a2;
|
||||
coeff[3] = this.Devinfo.bochangxishu.a3;
|
||||
this.option = {
|
||||
// ECharts 配置选项
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: false,// 显示连续的刻度
|
||||
min: 0,
|
||||
max: 510,
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside', // 内置数据区域缩放
|
||||
start: 0, // 初始缩放范围的起始位置(0%)
|
||||
end: 100 // 初始缩放范围的结束位置(100%)
|
||||
}
|
||||
]
|
||||
},
|
||||
animation: false,
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
//min:0,
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '10%',
|
||||
top: '5%'
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside', // 内置数据区域缩放,包括滚轮缩放
|
||||
xAxisIndex: [0], // 对应 x 轴
|
||||
filterMode: 'none' // 不过滤数据
|
||||
},
|
||||
{
|
||||
type: 'inside', // 内置数据区域缩放,包括滚轮缩放
|
||||
yAxisIndex: [0], // 对应 y 轴
|
||||
filterMode: 'none' // 不过滤数据
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
// legend: {
|
||||
// data: ['曲线'], // 图例名称
|
||||
// show: true ,// 显示图例
|
||||
// //selectedMode: 'multiple', // 图例的选择模式。默认开启图例开关,可选single,multiple
|
||||
// },
|
||||
series: [
|
||||
{
|
||||
data: [[1, 150], [2, 230], [3, 224], [4, 218], [5, 135], [6, 147], [7, 260]], // 使用二维数组表示数据点的坐标
|
||||
type: 'line',
|
||||
symbol: 'none', // 不显示数据点
|
||||
smooth: false, // 不使用平滑处理
|
||||
//step: 'start' // 设置 step 类型的起始位置
|
||||
}
|
||||
]
|
||||
};
|
||||
this.option.xAxis.max = coeff[3];
|
||||
let bandsum = this.Devinfo.bandsum;
|
||||
this.option.xAxis.min = bandsum * bandsum * bandsum * coeff[0] + bandsum * bandsum * coeff[1] + bandsum * coeff[2] + coeff[3];
|
||||
if (this.option.xAxis.max < this.option.xAxis.min) {
|
||||
let temp = this.option.xAxis.min;
|
||||
this.option.xAxis.min = this.option.xAxis.max;
|
||||
this.option.xAxis.max = temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
chart.setOption(this.option);
|
||||
|
||||
chart.dispatchAction({
|
||||
type: 'resize',
|
||||
|
||||
// 可以指定宽和高,如果不指定则默认取容器的大小
|
||||
// width: '新的宽度',
|
||||
// height: '新的高度'
|
||||
});
|
||||
if (this.fiber_type == "Dual") {
|
||||
|
||||
this.optiondown = JSON.parse(JSON.stringify(this.option));
|
||||
|
||||
coeff[0] = this.Devinfo.bochangxishu2.a0;
|
||||
coeff[1] = this.Devinfo.bochangxishu2.a1;
|
||||
coeff[2] = this.Devinfo.bochangxishu2.a2;
|
||||
coeff[3] = this.Devinfo.bochangxishu2.a3;
|
||||
|
||||
this.optiondown.xAxis.max = coeff[3];
|
||||
|
||||
this.optiondown.xAxis.min = bandsum * bandsum * bandsum * coeff[0] + bandsum * bandsum * coeff[1] + bandsum * coeff[2] + coeff[3];
|
||||
|
||||
if (this.optiondown.xAxis.max < this.optiondown.xAxis.min) {
|
||||
let temp = this.optiondown.xAxis.min;
|
||||
this.optiondown.xAxis.min = this.optiondown.xAxis.max;
|
||||
this.optiondown.xAxis.max = temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let chart_down = echarts.init(this.$refs.chart_weavelenth_down);
|
||||
chart_down.setOption(this.optiondown);
|
||||
chart_down.dispatchAction({
|
||||
type: 'resize',
|
||||
|
||||
// 可以指定宽和高,如果不指定则默认取容器的大小
|
||||
// width: '新的宽度',
|
||||
// height: '新的高度'
|
||||
});
|
||||
}
|
||||
|
||||
let that = this;
|
||||
chart.resize();
|
||||
window.addEventListener('resize', function () {
|
||||
that.echartresize();
|
||||
});
|
||||
},
|
||||
echartresize() {
|
||||
console.log("resize")
|
||||
const chartDom = this.$refs.chart;
|
||||
|
||||
|
||||
let chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
||||
let chart_down = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
||||
|
||||
chart_up.resize();
|
||||
chart_down.resize();
|
||||
|
||||
|
||||
},
|
||||
async findpeak(specindex) {
|
||||
if (specindex == 0) {
|
||||
let dataforpeak = this.Data.data;
|
||||
var peaks = await invoke("find_peek", { data: dataforpeak, minheigh: 3000 });
|
||||
console.log(peaks);
|
||||
let peaksforshow = [];
|
||||
let coeffweave1 = this.Devinfo.bochangxishu.a0;
|
||||
let coeffweave2 = this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3 = this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4 = this.Devinfo.bochangxishu.a3;
|
||||
|
||||
var lenthofpeaks=this.Peaks.length;
|
||||
for (var i=lenthofpeaks-1;i>=0;i--){
|
||||
if (this.Peaks[i][3] == false){
|
||||
this.Peaks.splice(i,1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//this.Peaks = [];
|
||||
|
||||
let peakformatch = [];
|
||||
peaks.forEach(element => {
|
||||
var weave = coeffweave1 * element[0] * element[0] * element[0] + coeffweave2 * element[0] * element[0] + coeffweave3 * element[0] + coeffweave4;
|
||||
peaksforshow.push([weave, element[1], element[0]]);
|
||||
this.Peaks.push([weave, element[1], element[0], false, 0])
|
||||
peakformatch.push(element[0]);
|
||||
});
|
||||
peakformatch.sort(function (a, b) {
|
||||
return a - b;
|
||||
});
|
||||
let weaveformatch = this.WeavePeaksDeffine.slice(1, this.WeavePeaksDeffine.length);
|
||||
|
||||
this.matchSpectrumPeaks(peakformatch, weaveformatch, { minMatchRatio: 0.8,
|
||||
maxGap: 1})
|
||||
|
||||
//peaks 按照第一列重新排序
|
||||
this.Peaks.sort(function (a, b) {
|
||||
return a[2] - b[2];
|
||||
});
|
||||
|
||||
let chartpeak =
|
||||
{
|
||||
data: peaksforshow, // 使用二维数组表示数据点的坐标
|
||||
type: 'scatter',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: function (params) {
|
||||
return params.value[2]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this.option.series.length < 2) {
|
||||
this.option.series.push(chartpeak);
|
||||
}
|
||||
else {
|
||||
this.option.series[1] = chartpeak;
|
||||
}
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
||||
chart_up.setOption(this.option);
|
||||
|
||||
}
|
||||
|
||||
else if (specindex == 1) {
|
||||
let dataforpeak = this.DataDown.data;
|
||||
var peaks = await invoke("find_peek", { data: dataforpeak, minheigh: 3000 });
|
||||
console.log(peaks);
|
||||
let peaksforshow = [];
|
||||
let coeffweave1 = this.Devinfo.bochangxishu2.a0;
|
||||
let coeffweave2 = this.Devinfo.bochangxishu2.a1;
|
||||
let coeffweave3 = this.Devinfo.bochangxishu2.a2;
|
||||
let coeffweave4 = this.Devinfo.bochangxishu2.a3;
|
||||
var lenthofpeaks=this.PeaksDown.length;
|
||||
for (var i=lenthofpeaks-1;i>=0;i--){
|
||||
if (this.PeaksDown[i][3] == false){
|
||||
this.PeaksDown.splice(i,1);
|
||||
|
||||
}
|
||||
}
|
||||
// this.PeaksDown = [];
|
||||
peaks.forEach(element => {
|
||||
var weave = coeffweave1 * element[0] * element[0] * element[0] + coeffweave2 * element[0] * element[0] + coeffweave3 * element[0] + coeffweave4;
|
||||
peaksforshow.push([weave, element[1], element[0]]);
|
||||
this.PeaksDown.push([weave, element[1], element[0], false, 0])
|
||||
});
|
||||
|
||||
|
||||
|
||||
this.PeaksDown.sort(function (a, b) {
|
||||
return a[2] - b[2];
|
||||
});
|
||||
|
||||
|
||||
let chartpeak =
|
||||
{
|
||||
data: peaksforshow, // 使用二维数组表示数据点的坐标
|
||||
type: 'scatter',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: function (params) {
|
||||
return params.value[2]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this.optiondown.series.length < 2) {
|
||||
this.optiondown.series.push(chartpeak);
|
||||
}
|
||||
else {
|
||||
this.optiondown.series[1] = chartpeak;
|
||||
}
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
||||
chart_up.setOption(this.optiondown);
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
async ClearArry(specindex){
|
||||
if (specindex == 0) {
|
||||
this.Peaks = [];
|
||||
this.option.series[1].data = [];
|
||||
|
||||
} else if (specindex == 1) {
|
||||
this.PeaksDown = [];
|
||||
this.optiondown.series[1].data = [];
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
ReplotWeaveInfo(spectralnumber) {
|
||||
let orgoption = {};
|
||||
let Peaksnow = [];
|
||||
if (spectralnumber == 0) {
|
||||
orgoption = this.option;
|
||||
Peaksnow = this.Peaks;
|
||||
} else if (spectralnumber == 1) {
|
||||
orgoption = this.optiondown;
|
||||
Peaksnow = this.PeaksDown;
|
||||
}
|
||||
if (orgoption.series.length < 2) {
|
||||
return;
|
||||
}
|
||||
let peaksforshow = [];
|
||||
Peaksnow.forEach(element => {
|
||||
if (element[3] == true || element[4] != 0) {
|
||||
var weave = element[0];
|
||||
if (element[1] > 3500) {
|
||||
peaksforshow.push([weave, element[1] - 500, element[4]]);
|
||||
} else {
|
||||
peaksforshow.push([weave, element[1] + 500, element[4]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
let chartpeak =
|
||||
{
|
||||
data: peaksforshow, // 使用二维数组表示数据点的坐标
|
||||
type: 'scatter',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: function (params) {
|
||||
return "波长:" + params.value[2]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (orgoption.series.length < 3) {
|
||||
orgoption.series.push(chartpeak);
|
||||
} else {
|
||||
orgoption.series[2] = chartpeak;
|
||||
}
|
||||
if (spectralnumber == 0) {
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
||||
chart_up.setOption(orgoption);
|
||||
} else if (spectralnumber == 1) {
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
||||
chart_up.setOption(orgoption);
|
||||
}
|
||||
|
||||
},
|
||||
async GetDataDrection(specindex) {
|
||||
if (specindex == 0) {
|
||||
var ret = await SensorMethod.Dev_Opt(80, 2);
|
||||
this.shutter_time_up=ret;
|
||||
// this.shutter_time_up = ret.shuttertimes;
|
||||
// this.sensor_gain_up = ret.gain;
|
||||
this.GetOneData();
|
||||
}
|
||||
else if (specindex == 1) {
|
||||
var ret = await SensorMethod.Dev_Opt_Two(80, 3);
|
||||
this.shutter_time_down = ret.shuttertimes;
|
||||
this.sensor_gain_down = ret.gain;
|
||||
this.GetOneDatadown();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
async GetOneDatadown() {
|
||||
let coeffweave1 = this.Devinfo.bochangxishu2.a0;
|
||||
let coeffweave2 = this.Devinfo.bochangxishu2.a1;
|
||||
let coeffweave3 = this.Devinfo.bochangxishu2.a2;
|
||||
let coeffweave4 = this.Devinfo.bochangxishu2.a3;
|
||||
await SensorMethod.Set_Gain(this.sensor_gain_down);
|
||||
// await SensorMethod.Get_Date_on_Derction("UP", this.shutter_time_down, false, 1)
|
||||
var data = await SensorMethod.Get_Date_on_Derction("DOWN", this.shutter_time_down, false, 1)
|
||||
this.DataDown = data; //获取波长系数
|
||||
var lenthofdata = data.data.length;
|
||||
let dataforshow = [];
|
||||
for (var i = 0; i < lenthofdata; i++) {
|
||||
var weave = coeffweave1 * i * i * i + coeffweave2 * i * i + coeffweave3 * i + coeffweave4;
|
||||
dataforshow.push([weave, data.data[i]]);
|
||||
}
|
||||
this.optiondown.series[0].data = dataforshow;
|
||||
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
||||
chart_up.setOption(this.optiondown);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(dataforshow);
|
||||
|
||||
},
|
||||
|
||||
async GetOneData() {
|
||||
let coeffweave1 = this.Devinfo.bochangxishu.a0;
|
||||
let coeffweave2 = this.Devinfo.bochangxishu.a1;
|
||||
let coeffweave3 = this.Devinfo.bochangxishu.a2;
|
||||
let coeffweave4 = this.Devinfo.bochangxishu.a3;
|
||||
await SensorMethod.Set_Gain(this.sensor_gain_up);
|
||||
var data = await SensorMethod.Get_Date_on_Derction("UP", this.shutter_time_up, false, 1)
|
||||
this.Data = data; //获取波长系数
|
||||
var lenthofdata = data.data.length;
|
||||
let dataforshow = [];
|
||||
for (var i = 0; i < lenthofdata; i++) {
|
||||
var weave = coeffweave1 * i * i * i + coeffweave2 * i * i + coeffweave3 * i + coeffweave4;
|
||||
dataforshow.push([weave, data.data[i]]);
|
||||
}
|
||||
this.option.series[0].data = dataforshow;
|
||||
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
||||
chart_up.setOption(this.option);
|
||||
|
||||
// this.GetOneDatadown()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(dataforshow);
|
||||
|
||||
},
|
||||
async CompuWeaveLenth(spectralnumber) {
|
||||
let orgdata = [];
|
||||
if (spectralnumber == 0) {
|
||||
orgdata = this.Peaks;
|
||||
|
||||
} else if (spectralnumber == 1) {
|
||||
orgdata = this.PeaksDown;
|
||||
}
|
||||
let Xdata = [];
|
||||
let Ydata = [];
|
||||
orgdata.forEach(element => {
|
||||
if (element[3] == true) {
|
||||
Xdata.push(Number(element[2]));
|
||||
Ydata.push(Number(element[4]));
|
||||
}
|
||||
});
|
||||
if (Xdata.length < 4) {
|
||||
alert("至少选择4个峰");
|
||||
return;
|
||||
}
|
||||
let result = await invoke("compute_weave_coeff", { x: Xdata, y: Ydata });
|
||||
if (spectralnumber == 0) {
|
||||
this.Devinfo.bochangxishu.a0 = result[3];
|
||||
this.Devinfo.bochangxishu.a1 = result[2];
|
||||
this.Devinfo.bochangxishu.a2 = result[1];
|
||||
this.Devinfo.bochangxishu.a3 = result[0];
|
||||
let coeff = [];
|
||||
coeff[0] = this.Devinfo.bochangxishu.a0;
|
||||
coeff[1] = this.Devinfo.bochangxishu.a1;
|
||||
coeff[2] = this.Devinfo.bochangxishu.a2;
|
||||
coeff[3] = this.Devinfo.bochangxishu.a3;
|
||||
|
||||
this.option.xAxis.max = coeff[3];
|
||||
let bandsum = this.Devinfo.bandsum;
|
||||
this.option.xAxis.min = bandsum * bandsum * bandsum * coeff[0] + bandsum * bandsum * coeff[1] + bandsum * coeff[2] + coeff[3];
|
||||
if (this.option.xAxis.max < this.option.xAxis.min) {
|
||||
let temp = this.option.xAxis.min;
|
||||
this.option.xAxis.min = this.option.xAxis.max;
|
||||
this.option.xAxis.max = temp;
|
||||
}
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth);
|
||||
chart_up.setOption(this.option);
|
||||
|
||||
} else if (spectralnumber == 1) {
|
||||
this.Devinfo.bochangxishu2.a0 = result[3];
|
||||
this.Devinfo.bochangxishu2.a1 = result[2];
|
||||
this.Devinfo.bochangxishu2.a2 = result[1];
|
||||
this.Devinfo.bochangxishu2.a3 = result[0];
|
||||
let coeff = [];
|
||||
coeff[0] = this.Devinfo.bochangxishu2.a0;
|
||||
coeff[1] = this.Devinfo.bochangxishu2.a1;
|
||||
coeff[2] = this.Devinfo.bochangxishu2.a2;
|
||||
coeff[3] = this.Devinfo.bochangxishu2.a3;
|
||||
this.optiondown.xAxis.max = coeff[3];
|
||||
let bandsum = this.Devinfo.bandsum;
|
||||
this.optiondown.xAxis.min = bandsum * bandsum * bandsum * coeff[0] + bandsum * bandsum * coeff[1] + bandsum * coeff[2] + coeff[3];
|
||||
if (this.optiondown.xAxis.max < this.optiondown.xAxis.min) {
|
||||
let temp = this.optiondown.xAxis.min;
|
||||
this.optiondown.xAxis.min = this.optiondown.xAxis.max;
|
||||
this.optiondown.xAxis.max = temp;
|
||||
}
|
||||
var chart_up = echarts.getInstanceByDom(this.$refs.chart_weavelenth_down);
|
||||
chart_up.setOption(this.optiondown);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
async Set_Weave_Coeff() {
|
||||
SensorMethod.Set_Weave_Coeff(0, this.Devinfo.bochangxishu.a0, this.Devinfo.bochangxishu.a1, this.Devinfo.bochangxishu.a2, this.Devinfo.bochangxishu.a3);
|
||||
if (this.Devinfo.fiber_type == "Dual")
|
||||
SensorMethod.Set_Weave_Coeff(1, this.Devinfo.bochangxishu2.a0, this.Devinfo.bochangxishu2.a1, this.Devinfo.bochangxishu2.a2, this.Devinfo.bochangxishu2.a3);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 光谱峰自动匹配函数
|
||||
* @param {number[]} detectedPeaks - 检测到的峰位置数组(单位:像素或通道号)
|
||||
* @param {number[]} referencePeaks - 参考峰波长数组(单位:nm)
|
||||
* @param {Object} [options] - 可选参数
|
||||
* @param {number} [options.tolerance=5] - 初始匹配容差(像素)
|
||||
* @param {number} [options.minMatches=3] - 要求的最小匹配数
|
||||
* @returns {number[]} 匹配成功的检测峰索引数组(按referencePeaks顺序对应)
|
||||
*/
|
||||
async matchSpectrumPeaks(detected, reference, options = {}) {
|
||||
console.log("detectedPeaks");
|
||||
console.log(detected);
|
||||
console.log("referencePeaks");
|
||||
|
||||
console.log(reference);
|
||||
const {
|
||||
ratioTolerance = 0.15, // 比例允许误差±15%
|
||||
minPeakDistance = 5, // 忽略间距过小的峰
|
||||
debug = true
|
||||
} = options;
|
||||
// 1. 生成参考峰的所有可能三点组合
|
||||
const refTriplets = [];
|
||||
for (let i = 0; i < reference.length - 2; i++) {
|
||||
const a = reference[i], b = reference[i+1], c = reference[i+2];
|
||||
const ratio = (c - b) / (b - a);
|
||||
refTriplets.push({ a, b, c, ratio, index: i });
|
||||
if (debug) console.log(`参考组合#${i}: [${a},${b},${c}] 比例=${ratio.toFixed(3)}`);
|
||||
}
|
||||
// 2. 预处理检测峰(合并过近的峰)
|
||||
const filteredPeaks = detected.filter((p, i) =>
|
||||
i === 0 || p - detected[i-1] > minPeakDistance
|
||||
);
|
||||
// 3. 在检测峰中寻找最佳匹配
|
||||
let bestMatch = null;
|
||||
for (let i = 0; i < filteredPeaks.length - 2; i++) {
|
||||
const da = filteredPeaks[i], db = filteredPeaks[i+1], dc = filteredPeaks[i+2];
|
||||
const detRatio = (dc - db) / (db - da);
|
||||
|
||||
// 与所有参考组合对比
|
||||
for (const ref of refTriplets) {
|
||||
const ratioError = Math.abs(detRatio - ref.ratio) / ref.ratio;
|
||||
|
||||
if (ratioError < ratioTolerance) {
|
||||
const scale = (db - da) / (ref.b - ref.a); // 计算缩放因子
|
||||
const confidence = 1 - ratioError;
|
||||
|
||||
if (!bestMatch || confidence > bestMatch.confidence) {
|
||||
bestMatch = {
|
||||
refTriplet: [ref.a, ref.b, ref.c],
|
||||
detTriplet: [da, db, dc],
|
||||
scale,
|
||||
ratioError,
|
||||
confidence,
|
||||
refIndex: ref.index,
|
||||
detIndex: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 4. 结果验证与扩展
|
||||
if (bestMatch) {
|
||||
if (debug) {
|
||||
console.log(`最佳匹配:
|
||||
参考峰[${bestMatch.refTriplet.join(',')}] 比例=${((bestMatch.refTriplet[2]-bestMatch.refTriplet[1])/(bestMatch.refTriplet[1]-bestMatch.refTriplet[0])).toFixed(3)}
|
||||
检测峰[${bestMatch.detTriplet.join(',')}] 比例=${((bestMatch.detTriplet[2]-bestMatch.detTriplet[1])/(bestMatch.detTriplet[1]-bestMatch.detTriplet[0])).toFixed(3)}
|
||||
缩放因子=${bestMatch.scale.toFixed(2)} 置信度=${(bestMatch.confidence*100).toFixed(1)}%`);
|
||||
}
|
||||
// 扩展验证其他峰
|
||||
const predictedAll = reference.map(w =>
|
||||
bestMatch.detTriplet[0] + (w - bestMatch.refTriplet[0]) * bestMatch.scale
|
||||
);
|
||||
return { ...bestMatch, predictedAll };
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="weavecontainer" style="width:100%;height: 100% !important;margin: 0px;padding: 20px">
|
||||
<div class="row" style="height: 100%">
|
||||
|
||||
|
||||
<div class="col-2" style="height: 100%;">
|
||||
<BCard header="sensor 1" header-text-variant="white" header-tag="header" header-bg-variant="dark"
|
||||
style="max-width: 20rem">
|
||||
<BCardText><b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a0</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu.a0"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
<b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a1</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu.a1"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
<b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a2</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu.a2"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
<b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a3</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu.a3"></b-form-input>
|
||||
</b-input-group>
|
||||
</BCardText>
|
||||
</BCard>
|
||||
<BCard header="sensor 2" header-text-variant="white" header-tag="header" header-bg-variant="dark"
|
||||
style="max-width: 20rem" v-if="fiber_type == 'Dual'">
|
||||
<BCardText><b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a0</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu2.a0"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
<b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a1</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu2.a1"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
<b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a2</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu2.a2"></b-form-input>
|
||||
</b-input-group>
|
||||
|
||||
<b-input-group class="my-1">
|
||||
<BInputGroupPrepend is-text class="myinputprepend">a3</BInputGroupPrepend>
|
||||
<b-form-input type="number" step="0.00000000000001" v-model="Devinfo.bochangxishu2.a3"></b-form-input>
|
||||
</b-input-group>
|
||||
</BCardText>
|
||||
</BCard>
|
||||
|
||||
|
||||
<p style="position:absolute ;bottom: 10px;width: 100%;height: 30px">
|
||||
<b-button @click="Set_Weave_Coeff" style="position:absolute;left: 20px ">设置</b-button>
|
||||
<b-button @click="GetSenSorInfo" style="position:absolute;right: 20px ">恢复</b-button>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="col-10" style="height: 100%;">
|
||||
|
||||
<div style="height: 100%;width: 100%;">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row linbox" :style="fiber_type == 'Dual' ? 'height: 50%' : 'height: 100%'">
|
||||
<b-button @click="findpeak(0)"
|
||||
style="position:absolute;right: 20%;margin-top:5px;z-index: 10;width: 60px; ">寻峰</b-button>
|
||||
<b-button @click="GetDataDrection(0)"
|
||||
style="position:absolute;right: 20%;margin-top:5%; z-index: 10; ;width: 60px ">采集</b-button>
|
||||
|
||||
<a-tag style="position:absolute;right: 20%;margin-top:10%; z-index: 10; ;width: 80px ">{{
|
||||
shutter_time_up.toFixed(2) }} ms</a-tag>
|
||||
<a-tag style="position:absolute;right: 20%;margin-top:13%; z-index: 10; ;width: 80px ">{{
|
||||
sensor_gain_up.toFixed(2) }} </a-tag>
|
||||
<b-button @click="CompuWeaveLenth(0)"
|
||||
style="position:absolute;right: 20%;margin-top:15%; z-index: 10; ;width: 60px ">计算</b-button>
|
||||
<b-button @click="ClearArry(0)"
|
||||
style="position:absolute;right: 20%;margin-top:20%; z-index: 10; ;width: 60px ">清空</b-button>
|
||||
<div class="chart-container" ref="chart_weavelenth"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="width: 20%; overflow: auto;height:80%;">
|
||||
|
||||
<a-row style="border-top: 1px solid ;border-bottom: 1px solid ;border-color: gray;">
|
||||
|
||||
<a-col :span="8" style="font-size:small; text-align: center;">像素</a-col>
|
||||
<a-col :span="4" style="font-size:small;text-align: center;">启用</a-col>
|
||||
<a-col :span="10" style="font-size:small;text-align: center;">波长</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row v-for="peak in Peaks" :key="peak[2]"
|
||||
style="font-size: small;text-align: center;border-bottom: 1px solid ;border-color: gray;">
|
||||
|
||||
<a-col :span="8" style="font-size:small; text-align: center;">{{ peak[2] }}</a-col>
|
||||
<a-col :span="4" style="font-size:small;text-align: center;"> <a-checkbox
|
||||
v-model="peak[3]"></a-checkbox></a-col>
|
||||
<a-col :span="12" style="font-size:small;text-align: center;">
|
||||
<!-- <a-input v-model="peak[4]" @change="ReplotWeaveInfo(0)"></a-input> -->
|
||||
<select style="width: 100%;" placeholder="Please select ..." allow-create
|
||||
@change="ReplotWeaveInfo(0)" v-model="peak[4]">
|
||||
|
||||
<option v-for="item in WeavePeaksDeffine" :key="item" :value="item">
|
||||
{{ item }}
|
||||
</option>
|
||||
</select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="row linbox" v-if="fiber_type == 'Dual'">
|
||||
<b-button @click="findpeak(1)"
|
||||
style="position:absolute;right: 20%;margin-top:5px; z-index: 10; ;width: 60px ">寻峰</b-button>
|
||||
<b-button @click="GetDataDrection(1)"
|
||||
style="position:absolute;right: 20%;margin-top:5%; z-index: 10; ;width: 60px ">采集</b-button>
|
||||
<a-tag style="position:absolute;right: 20%;margin-top:13%; z-index: 10; ;width: 80px ">{{
|
||||
sensor_gain_down.toFixed(2) }} </a-tag>
|
||||
<a-tag style="position:absolute;right: 20%;margin-top:10%; z-index: 10; ;width: 80px ">{{
|
||||
shutter_time_down.toFixed(2) }} ms</a-tag>
|
||||
<b-button @click="CompuWeaveLenth(1)"
|
||||
style="position:absolute;right: 20%;margin-top:15%; z-index: 10; ;width: 60px ">计算</b-button>
|
||||
<b-button @click="ClearArry(1)"
|
||||
style="position:absolute;right: 20%;margin-top:20%; z-index: 10; ;width: 60px ">清空</b-button>
|
||||
<!-- <b-button @click="findpeak(1)" style="position:absolute;right: 20%;margin-top:20%; z-index: 10; ;width: 60px ">寻峰</b-button> -->
|
||||
<div class="chart-container" ref="chart_weavelenth_down"></div>
|
||||
<div style="width: 20%; overflow: auto;height:80%;">
|
||||
|
||||
<a-row style="border-top: 1px solid ;border-bottom: 1px solid ;border-color: gray;">
|
||||
|
||||
<a-col :span="8" style="font-size:small; text-align: center;">像素</a-col>
|
||||
<a-col :span="4" style="font-size:small;text-align: center;">启用</a-col>
|
||||
<a-col :span="10" style="font-size:small;text-align: center;">波长</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row v-for="peak in PeaksDown" :key="peak[2]"
|
||||
style="font-size: small;text-align: center;border-bottom: 1px solid ;border-color: gray;">
|
||||
|
||||
<a-col :span="8" style="font-size:small; text-align: center;">{{ peak[2] }}</a-col>
|
||||
<a-col :span="4" style="font-size:small;text-align: center;"> <a-checkbox
|
||||
v-model="peak[3]"></a-checkbox></a-col>
|
||||
<a-col :span="12" style="font-size:small;text-align: center;">
|
||||
<!-- <a-input v-model="peak[4]"></a-input> -->
|
||||
<a-select style="width: 100%;" placeholder="Please select ..." allow-create
|
||||
@change="ReplotWeaveInfo(1)" v-model="peak[4]">
|
||||
<a-option v-for="item in WeavePeaksDeffine" :key="item" :value="item">
|
||||
{{ item }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.linbox {
|
||||
/* / width: 100vw; */
|
||||
height: 50%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border-bottom: 1px solid #d2dede;
|
||||
position: static;
|
||||
|
||||
}
|
||||
|
||||
.col-2 {
|
||||
background-color: #f8f9fa;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding: 0px;
|
||||
border-right: 1px solid #d2dede;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.col-10 {
|
||||
padding: 0px;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
background-color: #f8f9fa;
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #f8f9fa;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
102
src/components/menubox/help.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="markdown-container help">
|
||||
<vue-markdown :source="markdownContent" :options="markdownOptions"></vue-markdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueMarkdown from 'vue-markdown-render'; // 注意这里的导入路径可能因库版本而异
|
||||
import {fs} from "@tauri-apps/api";
|
||||
|
||||
// 导入一个 highlight.js 的主题样式,例如 dracula
|
||||
// 你需要安装 highlight.js:npm install highlight.js
|
||||
// import 'highlight.js/styles/dracula.css'; // 你可以选择其他主题样式
|
||||
export default {
|
||||
name: 'MarkdownViewerComponent',
|
||||
components: {
|
||||
VueMarkdown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: 'Vue 中展示 Markdown (使用组件)',
|
||||
markdownContent: "",
|
||||
markdownOptions: {
|
||||
gfm: true, // 启用 GitHub Flavored Markdown
|
||||
breaks: true, // 将单个换行符渲染为 <br>
|
||||
// highlight 选项用于代码块高亮
|
||||
highlight: function(code, lang) {
|
||||
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
|
||||
return hljs.highlight(code, { language }).value;
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadMarkdownContent();
|
||||
},
|
||||
methods: {
|
||||
async loadMarkdownContent() {
|
||||
try {
|
||||
// 确保文件路径正确,Tauri 应用中文件路径需要注意
|
||||
// 如果 updatelog.md 在应用的资源目录,可能需要使用 fs.appDataDir() 或 fs.resourceDir()
|
||||
// 这里假设它在应用启动的当前工作目录或通过bundle访问
|
||||
var configdata = await fs.readTextFile("updatelog.md");
|
||||
this.markdownContent = configdata;
|
||||
} catch (error) {
|
||||
console.error("Error reading markdown file:", error);
|
||||
this.markdownContent = "无法加载更新日志。";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.help {
|
||||
padding: 20px;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* 针对 markdown-container 增加滚动条和高度限制 */
|
||||
.markdown-container {
|
||||
/* 设置最大高度,例如:视口高度减去顶部或其他元素的高度 */
|
||||
/* 你可以根据实际布局调整这个值,例如固定的 500px */
|
||||
max-height: calc(100vh - 250px); /* 假设留出 150px 给其他内容或边距 */
|
||||
overflow-y: auto; /* 当内容超出最大高度时显示垂直滚动条 */
|
||||
/* 可以添加一些内边距,让滚动条不紧贴内容 */
|
||||
padding-right: 15px; /* 为滚动条留出空间,避免内容被遮挡 */
|
||||
box-sizing: border-box; /* 确保 padding 包含在 max-height 内 */
|
||||
}
|
||||
|
||||
|
||||
.help h1 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.help p {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 如果需要,可以进一步美化滚动条 */
|
||||
/* 适用于 WebKit 浏览器 (Chrome, Safari, Edge) */
|
||||
.markdown-container::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
|
||||
}
|
||||
|
||||
.markdown-container::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.markdown-container::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.markdown-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
</style>
|
||||
@ -6,7 +6,7 @@ import {ref} from 'vue';
|
||||
import Mycard from "./mycard.vue";
|
||||
import EventBus from "../eventBus.js";
|
||||
import {fs} from "@tauri-apps/api";
|
||||
|
||||
import SerialportMethod from "./SerialPort/SerialportMethod.js";
|
||||
export default {
|
||||
name: "siderleft",
|
||||
components: {Mycard},
|
||||
@ -87,7 +87,8 @@ export default {
|
||||
isenable:false,
|
||||
begin:"00:00",
|
||||
end:"23:59",
|
||||
}
|
||||
},
|
||||
continuessave:false,
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
@ -113,6 +114,10 @@ export default {
|
||||
this.Dispatcher.begin=configdata.Dispatcher.begin
|
||||
if (typeof(configdata.Dispatcher.end)!="undefined")
|
||||
this.Dispatcher.end=configdata.Dispatcher.end
|
||||
if (typeof(configdata.sensor_typeforset)!="undefined")
|
||||
this.sensor_typeforset=configdata.sensor_typeforset
|
||||
|
||||
await SerialportMethod.Set_Dev_Type(this.sensor_typeforset);;
|
||||
|
||||
|
||||
var ports = this.listSerialPorts();
|
||||
@ -170,9 +175,10 @@ export default {
|
||||
<BAccordionItem title="高级设置" v-show="isSpecialmodeshow">
|
||||
<!-- 设备切换 a-select -->
|
||||
<b-input-group prepend="设备切换" size="sm" style="width: 100%">
|
||||
<b-form-select v-model="sensor_typeforset" style="padding-right: 8px" :update="onDevchange()">
|
||||
<b-form-select v-model="sensor_typeforset" style="padding-right: 8px" @change="onDevchange" :disabled="SerialInfo.isopen" >
|
||||
<b-form-select-option value="IRIS-IS11">高光谱传感器</b-form-select-option>
|
||||
<b-form-select-option value="JZ-IS11">IS11</b-form-select-option>
|
||||
<b-form-select-option value="IS3">IS3</b-form-select-option>
|
||||
<b-form-select-option value="IS11">IS11</b-form-select-option>
|
||||
</b-form-select>
|
||||
</b-input-group>
|
||||
|
||||
@ -252,7 +258,8 @@ export default {
|
||||
<b-form-select-option value="DOWN" v-if="Devinfo.sensor_type=='IRIS-IS11'" >{{ DOWNStr }}</b-form-select-option>
|
||||
<b-form-select-option value="DARK" v-if="Devinfo.sensor_type=='IRIS-IS11'">DARK</b-form-select-option>
|
||||
<b-form-select-option value="ALL" v-if="Devinfo.sensor_type=='IRIS-IS11'">ALL</b-form-select-option>
|
||||
<b-form-select-option value="RAD_UP" v-if="Devinfo.sensor_type=='IRIS-IS11'">RAD_UP</b-form-select-option>
|
||||
<b-form-select-option value="RAD_UP">RAD_UP</b-form-select-option>
|
||||
<!-- <b-form-select-option value="RAD_UP" v-if="Devinfo.sensor_type=='IRIS-IS11'">RAD_UP</b-form-select-option> -->
|
||||
<b-form-select-option value="RAD_DOWN" v-if="Devinfo.sensor_type=='IRIS-IS11'">RAD_DOWN</b-form-select-option>
|
||||
<b-form-select-option value="REF" v-if="Devinfo.sensor_type=='IRIS-IS11'">REF</b-form-select-option>
|
||||
|
||||
@ -284,16 +291,18 @@ export default {
|
||||
<b-input-group style="margin-bottom: 2px;width: 100%;margin-left: auto;margin-right: auto;align-items: center;" size="sm" >
|
||||
|
||||
<b-button @click="ContinueCelect(-1)" :disabled="iscollecting || !SerialInfo.isopen"
|
||||
style="min-width:80%;margin: auto;" v-show="!continuecaiji">
|
||||
连续保存
|
||||
style="min-width:60%;margin: auto;" v-show="!continuecaiji">
|
||||
连续
|
||||
<!-- 连续采集-->
|
||||
</b-button>
|
||||
<b-button @click="ContinueCelect(-1)" :disabled=" !SerialInfo.isopen"
|
||||
style="min-width:80%;margin: auto;" v-show="continuecaiji">
|
||||
停止保存
|
||||
style="min-width:60%;margin: auto;" v-show="continuecaiji">
|
||||
停止
|
||||
<!-- 连续采集-->
|
||||
</b-button>
|
||||
|
||||
<b-input-group-append>
|
||||
保存<input type="checkbox" style="margin: 10px" v-model="continuessave" :disabled="continuecaiji"/>
|
||||
</b-input-group-append>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ export default {
|
||||
configdata.useSG=this.dataprocessconfig.useSG;
|
||||
configdata.usehighpass=this.dataprocessconfig.usehighpass;
|
||||
configdata.Dispatcher=this.Dispatcher;
|
||||
configdata.sensor_typeforset=this.sensor_typeforset;
|
||||
fs.writeFile("config.json", JSON.stringify(configdata));
|
||||
EventBus.emit('showbox', {title: "系统", body: "保存配置成功",interval:10});
|
||||
this.isSpecialmodeshow=true;
|
||||
@ -111,8 +112,11 @@ export default {
|
||||
|
||||
await this.GetoneData("",Number(this.caijiavgNumber));
|
||||
var aa={code:"Space"}
|
||||
await this.handlekeydown(aa);
|
||||
if(this.continuessave)
|
||||
{ await this.handlekeydown(aa);
|
||||
await delay(50);
|
||||
}
|
||||
|
||||
// if (this.cajitimesjiange>0)
|
||||
// await delay(this.cajitimesjiange*1000-50);
|
||||
//等待期间每一秒检查一次是否停止
|
||||
@ -180,7 +184,7 @@ export default {
|
||||
//datatosave 保存
|
||||
console.log(this.datatosave)
|
||||
var data={};
|
||||
if (this.caijidirection=="UP"||this.caijidirection=="DARK")
|
||||
if (this.caijidirection=="UP"||this.caijidirection=="DARK"||this.caijidirection=="RAD_UP")
|
||||
{
|
||||
data =this.dataup;
|
||||
}else {
|
||||
@ -254,9 +258,21 @@ export default {
|
||||
var lenthofdataup=dataup.data.length;
|
||||
for (var i=0;i<lenthofdataup;i++)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(this.Devinfo.name=="IRIS-IS11")
|
||||
{
|
||||
yValues.push(dataup.data[lenthofdataup-i-1]);
|
||||
yvalues2.push(datadown.data[lenthofdataup-i-1]);
|
||||
}
|
||||
else{
|
||||
yValues.push(dataup.data[i]);
|
||||
yvalues2.push(datadown.data[i]);
|
||||
}
|
||||
}
|
||||
if (this.outputconfig.isChongCaiyang)
|
||||
{
|
||||
let aaa= await invoke("interpolate_spline",{x:xValues,y:yValues,step:this.outputconfig.ChongCaiyanginterval})
|
||||
@ -277,7 +293,7 @@ export default {
|
||||
else
|
||||
{
|
||||
var datatosave={};
|
||||
if (this.caijidirection=="UP")
|
||||
if (this.caijidirection=="UP"||this.caijidirection=="RAD_UP")
|
||||
{
|
||||
|
||||
datatosave=this.dataup;
|
||||
@ -316,8 +332,14 @@ export default {
|
||||
|
||||
var lenthofdataup=datatosave.data.length;
|
||||
for (var i=0;i<lenthofdataup;i++)
|
||||
{
|
||||
if(this.Devinfo.sensor_type=="IRIS-IS11")
|
||||
{
|
||||
yValues.push(datatosave.data[lenthofdataup-i-1]);
|
||||
}else {
|
||||
yValues.push(datatosave.data[i]);
|
||||
}
|
||||
|
||||
}
|
||||
var yValuesofchongcaiyang = []
|
||||
if (this.outputconfig.isChongCaiyang)
|
||||
@ -359,7 +381,7 @@ export default {
|
||||
}else{
|
||||
filepath=this.Pathtosave;
|
||||
}
|
||||
|
||||
filepath=this.pathofdir+"/"+this.Filename+this.nowNumber+"_"+this.caijidirection+".csv";
|
||||
await fs.writeFile( filepath, strcsv);
|
||||
eventBus.emit('showbox', {title: "系统", body: "保存数据 "+ filepath+" OK",interval:10});
|
||||
}else
|
||||
|
||||