| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 | using DevExpress.Diagram.Core.Shapes;using DevExpress.XtraBars.Docking2010;using DevExpress.XtraEditors;using DevExpress.XtraEditors.Controls;using DevExpress.XtraGantt.Scheduling;using DevExpress.XtraGauges.Win;using DevExpress.XtraSpreadsheet.DocumentFormats.Xlsb;using Ips.CorAlgorithm;using Ips.Library.Basic;using Ips.Library.DxpLib;using Ips.Library.Entity;using Ips.Sps.Tools.Xdcs;using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Globalization;using System.IO;using System.Linq;using System.Text;using System.Text.Json;using System.Threading.Tasks;using System.Windows.Forms;namespace Ips.Sps.Tools.TdmaCgs{    public partial class TdmaCgMainCtrl : DevExpress.XtraEditors.XtraUserControl    {        public TdmaCgMainCtrl()        {            InitializeComponent();            File1ButtonEdit.SetFileOpen(filter: FileFilterString.Dat);            File2ButtonEdit.SetFileOpen(filter: FileFilterString.Dat);            FsButtonEdit.SetUnitText("M");            DtoCenterButtonEdit.SetUnitText("us", false);            DtoRangeButtonEdit.SetUnitText("us", false);            SnrButtonEdit.SetUnitText("dB", false);            DfoRangeButtonEdit.SetUnitText("Hz", false);            DtoCorrButtonEdit.SetUnitText("us", false);            DfoCorrButtonEdit.SetUnitText("us", false);            MinTimeLenButtonEdit.SetUnitText("s");            FileTimeDateEdit.UseTimeEdit();            gvMain.UseDefaultSettings(new GridViewDefaultSetting()            {                Editable = true,                ShowRowNum = true            });        }        string vmfile = Path.Combine(SpsConst.VmFolder, "tdmacg.json");        TdmaCgViewModel vm;        CancellationTokenSource cts;        private void TdmaCgMainCtrl_Load(object sender, EventArgs e)        {            if (File.Exists(vmfile))            {                vm = JsonSerializer.Deserialize<TdmaCgViewModel>(File.ReadAllText(vmfile));            }            else            {                vm = new TdmaCgViewModel();            }            vm.PropertyChanged += Vm_PropertyChanged;            bsMain.DataSource = vm;        }        private void Vm_PropertyChanged(object sender, PropertyChangedEventArgs e)        {            switch (e.PropertyName)            {                case nameof(TdmaCgViewModel.File1):                    File1Changed();                    break;                case nameof(TdmaCgViewModel.FileTime):                    FileTimeChanged();                    break;                case nameof(TdmaCgViewModel.FileTimeLen):                    FileTimeLenChanged();                    break;                case nameof(TdmaCgViewModel.Fs):                    FsChanged();                    break;            }        }        bool isChanging;        void File1Changed()        {            string fileName = vm.File1;            if (fileName.IsNullOrWhitespace())            {                vm.FileTime = DateTime.MinValue;                return;            }            FileInfo fi = new FileInfo(fileName);            if (!fi.Exists) return;            var timeStr = fi.Name.Substring(0, 14);            if (DateTime.TryParseExact(timeStr, "yyyyMMddHHmmss", CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime fileTime))            {                vm.FileTime = fileTime;            }            if (vm.Fs > 1e-6)            {                vm.FileTimeLen = fi.Length / 4 / (vm.Fs * 1e6);            }            else if (vm.FileTimeLen > 1e-6)            {                vm.Fs = fi.Length / 4 / vm.FileTimeLen;            }        }        void FileTimeChanged()        {        }        void FileTimeLenChanged()        {            if (isChanging) return;            if (vm.File1.IsNullOrWhitespace()) return;            if (!File.Exists(vm.File1)) return;            isChanging = true;            try            {                FileInfo fi = new FileInfo(vm.File1);                vm.Fs = fi.Length / 4 / vm.FileTimeLen / 1000000;            }            finally            {                isChanging = false;            }        }        void FsChanged()        {            if (isChanging) return;            if (vm.File1.IsNullOrWhitespace()) return;            if (!File.Exists(vm.File1)) return;            isChanging = true;            try            {                FileInfo fi = new FileInfo(vm.File1);                vm.FileTimeLen = fi.Length / 4 / (vm.Fs * 1e6);            }            finally            {                isChanging = false;            }        }        private async void btnStart_Click(object sender, EventArgs e)        {            if (vm != null)            {                File.WriteAllText(vmfile, JsonSerializer.Serialize(vm));            }            if (vm.WorkItems.Count == 0) return;            if (ValidateModelState()) return;            if (cts != null) cts.Dispose();            cts = new CancellationTokenSource();            btnStart.Enabled = false;            btnStop.Enabled = true;            try            {                var workList = gvMain.GetVisibleRows<TdmaWorkItemViewModel>();                await ExecuteCsgjAsync(vm, workList);            }            catch (Exception ex)            {                ex.HandleCancelEx(err =>                {                    MsgHelper.ShowError(err.Message, err);                });            }            finally            {                btnStart.Enabled = true;                btnStop.Enabled = false;            }        }        async Task ExecuteCsgjAsync(TdmaCgViewModel vm, IEnumerable<TdmaWorkItemViewModel> workList)        {            if (workList.Any() is false)            {                MsgHelper.ShowMsg("参估列表为空!");                return;            }            var startTime = vm.FileTime;            var endTime = vm.FileTime.AddSeconds(vm.FileTimeLen);            var corOption = new CorOptions()            {                Fs = (int)(vm.Fs * 1e6),                DtoCenter = vm.DtoCenter,                DtoRange = vm.DtoRange,                Snr = vm.Snr,                DfoRange = vm.DfoRange,                DtoCorr = vm.DtoCorr,                DfoCorr = vm.DfoCorr            };            using var fr = new FileStream(vm.File1, FileMode.Open, FileAccess.Read);            foreach (var workItem in workList)            {                var slotList = workItem.SlotList.Where(m => m.SlotTime >= startTime && m.SlotTime < endTime);                if (slotList.IsNullOrEmpty()) continue;                if (vm.MinTimeLen > 1e-6 && slotList.Sum(m => m.TimeLenNs) >= vm.MinTimeLen * 1e9) continue;                var mainFile = Path.Combine(FolderConsts.Temp, GuidSeq.Instance.Create().ToString("N") + ".dat");                bool success = ExportMainFile(startTime, endTime, vm.File1, mainFile, slotList);                if (!success || !File.Exists(mainFile))                {                    MsgHelper.ShowMsg("获取主星时隙文件失败!");                    return;                }                try                {                    ExeResult<CorResult[]> res;                    if (vm.CalcType == Library.Entity.CorCalcType.Cpu)                    {                        res = await CocUtil.Calc(mainFile, vm.File2, corOption, token: cts.Token);                    }                    else                    {                        res = await CogUtil.Calc(mainFile, vm.File2, corOption, token: cts.Token);                    }                    workItem.Dto = 0;                    workItem.Dfo = 0;                    workItem.Snr = 0;                    if (res.ExitCode == 0 && res.Result.Length > 0)                    {                        var xgfItem = res.Result[0];                        workItem.Dto = xgfItem.Dto;                        workItem.Dfo = xgfItem.Dfo;                        workItem.Snr = xgfItem.Snr;                        workItem.Message = "";                    }                    else                    {                        workItem.Message = res.ExitMsg;                    }                    workItem.UseTime = res.RunTimeMs * 1.0 / 1000;                }                catch (Exception ex)                {                    workItem.UseTime = 0;                    workItem.Message = ex.Message;                }                finally                {                    FileUtil.DeleteIfExists(mainFile);                }            }        }        public bool ExportMainFile(DateTime startTime, DateTime endTime, string infile, string outfile, IEnumerable<TdmaSlotViewModel> slotList)        {            using var fr = new FileStream(infile, FileMode.Open, FileAccess.Read);            using var fw = new FileStream(outfile, FileMode.OpenOrCreate, FileAccess.Write);            foreach (var slotItem in slotList)            {                int slotStart = (int)Math.Floor((slotItem.SlotTime - startTime).TotalSeconds * vm.Fs * 1e6 + slotItem.SlotTimeNs * vm.Fs * 1e-3) * 4;                int slotLen = (int)Math.Floor(slotItem.TimeLenNs * vm.Fs * 1e-3) * 4;                fw.Seek(slotStart, SeekOrigin.Begin);                byte[] buf = new byte[slotLen];                fr.Read(buf, 0, buf.Length);                fw.Write(buf);            }            fw.Flush();            fw.Dispose();            return true;        }        private void btnStop_Click(object sender, EventArgs e)        {            cts?.Cancel();        }        private async void grpCgList_CustomButtonClick(object sender, BaseButtonEventArgs e)        {            cts?.Dispose();            cts = new CancellationTokenSource();            btnStart.Enabled = false;            btnStop.Enabled = true;            try            {                string caption = e.Button.Properties.Caption;                switch (caption)                {                    case "导入时隙":                        await ImportSlotAsync();                        break;                }            }            catch (Exception ex)            {                ex.HandleCancelEx(err =>                {                    MsgHelper.ShowError(err.Message, err);                });            }            finally            {                btnStart.Enabled = true;                btnStop.Enabled = false;            }        }        async Task ImportSlotAsync()        {            string filenames = ToolDialog.OpenFile("", "导入时隙文件", mutiSelect: true, filter: FileFilterString.Txt);            if (filenames.IsNullOrWhitespace()) return;            vm.SlotFile = filenames;            var allLines = Enumerable.Empty<string>();            foreach (var file in filenames.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))            {                var fileLines = await File.ReadAllLinesAsync(file, cts.Token);                allLines = allLines.Concat(fileLines);            }            var query = from line in allLines                        let lineArr = line.Split(',', StringSplitOptions.TrimEntries)                        where line.IsNotNullOrWhitespace() && lineArr.Length >= 7                        let tdmaSlot = new TdmaSlot()                        {                            SlotTime = DateTime.ParseExact(lineArr[0], "yyyyMMddHHmmss", CultureInfo.CurrentCulture),                            SlotTimeNs = (int)(long.Parse(lineArr[1]) % 1e9),                            TimeLenNs = long.Parse(lineArr[2]),                            FreqPoint = long.Parse(lineArr[3]),                            Rate = int.Parse(lineArr[4]),                            UserId = lineArr[5],                            MacAddr = lineArr[6]                        }                        group tdmaSlot by new { tdmaSlot.UserId, tdmaSlot.MacAddr, tdmaSlot.FreqPoint, tdmaSlot.Rate } into slotGrp                        select slotGrp;            vm.WorkItems.Clear();            foreach (var item in query)            {                TdmaWorkItemViewModel tdItem = new TdmaWorkItemViewModel()                {                    UserId = item.Key.UserId,                    MacAddr = item.Key.MacAddr,                    FreqPoint = item.Key.FreqPoint,                    Rate = item.Key.Rate                };                foreach (var slotSrc in item.OrderBy(m => m.SlotTime))                {                    tdItem.SlotList.Add(new TdmaSlotViewModel()                    {                        SlotTime = slotSrc.SlotTime,                        SlotTimeNs = slotSrc.SlotTimeNs,                        TimeLenNs = slotSrc.TimeLenNs                    });                }                vm.WorkItems.Add(tdItem);            }        }        private void File1ButtonEdit_EditValueChanged(object sender, EventArgs e)        {            var arg = e as ChangingEventArgs;            string fileName = arg?.NewValue?.ToString(); ;            if (fileName.IsNullOrWhitespace())            {                vm.FileTime = DateTime.MinValue;                return;            }            FileInfo fi = new FileInfo(fileName);            if (!fi.Exists)            {                MsgHelper.ShowError("文件不存在!");                return;            }            var timeStr = fi.Name.Substring(0, 14);            if (DateTime.TryParseExact(timeStr, "yyyyMMddHHmmss", CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime fileTime))            {                vm.FileTime = fileTime;            }            if (vm.Fs > 1e-6)            {                vm.FileTimeLen = fi.Length / 4 / (vm.Fs * 1e6);            }            else if (vm.FileTimeLen > 1e-6)            {                vm.Fs = fi.Length / 4 / vm.FileTimeLen;            }        }        private bool ValidateModelState()        {            dxError.ClearErrors();            if (vm.File1.IsNullOrWhitespace())            {                dxError.SetError(File1ButtonEdit, "请选择文件1");            }            if (vm.File2.IsNullOrWhitespace())            {                dxError.SetError(File2ButtonEdit, "请选择文件2");            }            if (vm.Fs < 1e-6)            {                dxError.SetError(FsButtonEdit, "采样率不能为空!");            }            if (vm.DtoRange < 1e-6)            {                dxError.SetError(DtoRangeButtonEdit, "时差范围必须大于0");            }            if (vm.DfoRange < 1e-6)            {                dxError.SetError(DfoRangeButtonEdit, "频差范围必须大于0");            }            if (vm.Snr < 1e-6)            {                dxError.SetError(SnrButtonEdit, "信噪必须大于0");            }            return dxError.HasErrors;        }        private void gvMain_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)        {            if (e.Button == MouseButtons.Right)            {                popGrid.ShowPopup(e.Location);            }        }        private async void btnMenuCg_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)        {            var workList = gvMain.GetVisibleRows<TdmaWorkItemViewModel>();            await ExecuteCsgjAsync(vm, workList);        }        private void btnExportSlotFile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)        {            var workList = gvMain.GetSelectRow<TdmaWorkItemViewModel>();            if (workList.IsNullOrEmpty())            {                MsgHelper.ShowMsg("请选择要导出的项");                return;            }            string outDir = ToolDialog.OpenFolder("时隙文件路径");            if (outDir.IsNullOrWhitespace()) return;            DirectoryUtil.CreateIfNotExists(outDir);            var startTime = vm.FileTime;            var endTime = vm.FileTime.AddSeconds(vm.FileTimeLen);            foreach (var workItem in workList)            {                var slotList = workItem.SlotList.Where(m => m.SlotTime >= startTime && m.SlotTime < endTime);                if (slotList.IsNullOrEmpty()) continue;                var outfile = $"{vm.FileTime:yyyyMMddHHmmss}_{workItem.FreqPoint}_{workItem.Rate}_{workItem.UserId}_{workItem.MacAddr}";                outfile = Path.Combine(outDir, outfile);                ExportMainFile(startTime, endTime, vm.File1, outfile, slotList);            }        }    }}
 |