You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

653 lines
22 KiB
C#

using Arction.Wpf.ChartingMVVM;
using Arction.Wpf.ChartingMVVM.Axes;
using Arction.Wpf.ChartingMVVM.Views.ViewXY;
using mseedChart.Core;
using mseedChart.MainModule.Models;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace mseedChart.MainModule.ViewModels
{
public class ChartPlotViewModel : BindableBase
{
#region variable
Dispatcher _dispatcher;
/// <summary>
/// Delegate for data generation.
/// </summary>
/// <summary>
/// 当前采样数
/// </summary>
public int CurPoints;
private readonly IEventAggregator _ea;
private int _selectResult = 0;
public int SelectResult
{
get { return _selectResult; }
set
{
SetProperty(ref _selectResult, value);
}
}
int _channelCount = 60; // Channel count.
double _samplingFrequency = 500; // Sampling frequency (Hz).
double _xLength = 10; // X axis length.
double _previousX = 0; // Latest X value on axis.
long _now; // Latest time stamp.
long _startTicks; // Controls timing.
long _samplesOutput; // Generated samples quantity.
// Constants
const double YMin = 30000; // Minimal y-value.
const double YMax = 33000; // Maximal y-value.
WavesModel _wavesModel;
#endregion
/// <summary>
/// Thread.
/// </summary>
private delegate void ChartUpdateFromThreadHandler(double[][] samples);
private ChartUpdateFromThreadHandler _chartUpdate;
private Random _rand = new Random((int)DateTime.Now.Ticks);
#region "属性"
private int _lChartCount = 1;
/// <summary>
/// 波形控件数量
/// </summary>
public int LChartCount
{
get { return _lChartCount; }
set { _lChartCount = value; }
}
public List<ShareProperty> WaveComList { get; set; }
private ShareProperty _wavesCombination;
/// <summary>
/// 波形组合
/// </summary>
public ShareProperty WavesCombination
{
get { return _wavesCombination; }
set
{
_wavesCombination = value;
SetWavesCombination();
}
}
private DataSourcesEnum _dataSources;
/// <summary>
/// 数据来源
/// </summary>
public DataSourcesEnum DataSources
{
get { return _dataSources; }
set { _dataSources = value; }
}
private DataTypeEnum _wavesType;
/// <summary>
/// 波形类型
/// </summary>
public DataTypeEnum WavesType
{
get { return _wavesType; }
set { _wavesType = value; }
}
private DisplayModeEnum _displayMode;
/// <summary>
/// 显示模式
/// </summary>
public DisplayModeEnum DisplayMode
{
get { return _displayMode; }
set { _displayMode = value; }
}
private ScollModeEnum _scollMode;
/// <summary>
/// 滚动方式
/// </summary>
public ScollModeEnum ScollMode
{
get { return _scollMode; }
set { _scollMode = value; }
}
private DateTime _startTime;
/// <summary>
/// 开始时间
/// </summary>
public DateTime StartTime
{
get { return _startTime; }
set { _startTime = value; }
}
private DateTime _endTime;
/// <summary>
/// 开始时间
/// </summary>
public DateTime EndTime
{
get { return _endTime; }
set { _endTime = value; }
}
private int _sampling = 500;
/// <summary>
/// 采样频率
/// </summary>
public int Sampling
{
get { return _sampling; }
set { _sampling = value; }
}
/// <summary>
/// 延时(min)
/// </summary>
public int DelayMin { get; set; } = 10;
/// <summary>
/// 文件数据位置
/// </summary>
public string FileDataPath { get; set; } = @"D:\TaySystemPath\Downloads";
private string _cachePath;
private int _cacheSize;
/// <summary>
/// 缓存大小
/// </summary>
public int CacheSize
{
get { return _cacheSize; }
set { _cacheSize = value; }
}
private ObservableCollection<int> _stationList;
/// <summary>
/// 台站列表
/// </summary>
public ObservableCollection<int> StationList
{
get { return _stationList; }
set { _stationList = value; }
}
private LightningChart _lChartAll;
/// <summary>
/// 所有波形
/// </summary>
public LightningChart LChartALL
{
get { return _lChartAll; }
set { _lChartAll = value; }
}
private LightningChart _lChartZ;
/// <summary>
/// Z通道波形
/// </summary>
public LightningChart LChartZ
{
get { return _lChartZ; }
set { _lChartZ = value; }
}
private LightningChart _lChartE;
/// <summary>
/// E通道波形
/// </summary>
public LightningChart LChartE
{
get { return _lChartE; }
set { _lChartE = value; }
}
private LightningChart _lChartN;
/// <summary>
/// N通道波形
/// </summary>
public LightningChart LChartN
{
get { return _lChartN; }
set { _lChartN = value; }
}
private FrameworkElement childContent;
public FrameworkElement ChildContent
{
get { return childContent; }
set { childContent = value; }
}
private Grid gridChart;
public Grid GridChart
{
get { return gridChart; }
set { gridChart = value; }
}
public List<StationModel> smList;
#endregion
public ChartPlotViewModel()
{
_dispatcher = Application.Current.Dispatcher;
SelectResult = 10;
var wcList = (WavesCombinationEnum[])Enum.GetValues(typeof(WavesCombinationEnum));
WaveComList = wcList.Select(value => new ShareProperty((int)value, value.ToString())).ToList();
WavesCombination = WaveComList.SingleOrDefault(wc => wc.ID == 0);
_chartUpdate = new ChartUpdateFromThreadHandler(FeedNewDataToChartPingPu);
_wavesModel = new WavesModel();
LChartALL.ViewXY.XAxes = new AxisXCollection();
LChartALL.ViewXY.XAxes.Add(_wavesModel.GetAxisX(10));
InitData();
(Application.Current.MainWindow as System.Windows.Window).Closing += ApplicationClosingDispose;
ShowWave();
}
private void ShowWave(string obj= "2023-03-29T06:41:21.348")
{
string EventTimeStr = obj;
string datePath = EventTimeStr.Substring(0, 4) + EventTimeStr.Substring(5, 2) + EventTimeStr.Substring(8, 2);
string dataFilePath = RegionNames.MseedFilePath + "\\" + datePath + "\\";
string dataFileName = "HA." + EventTimeStr.Substring(0, 4) + EventTimeStr.Substring(5, 2)
+ EventTimeStr.Substring(8, 2) + EventTimeStr.Substring(10, 3)
+ EventTimeStr.Substring(14, 2) + EventTimeStr.Substring(17, 2) + ".01" + RegionNames.DataTypeString;
string mseedStr = ".mseed";
string asciiSavePath = RegionNames.TxtFilePath + "\\" + datePath + "\\" + dataFileName + ".txt";
if (!Directory.Exists(dataFilePath))
{
Directory.CreateDirectory(dataFilePath);
}
if (!Directory.Exists(Path.GetDirectoryName(asciiSavePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(asciiSavePath));
}
//if (!File.Exists(dataFilePath + dataFileName + mseedStr))
{
//TaskData taskData = new TaskData();
//taskData.EventTimeStr = EventTimeStr;
//taskData.Tasks = new Task(() =>
//{
// int res = new DownloadWavedata().Download(EventTimeStr, dataFilePath, dataFileName + mseedStr, GlobalConfig.UseWaveDataTable);
// if (res > -1)
// {
// MSeed2Asc(dataFilePath + dataFileName + mseedStr, asciiSavePath);
// }
// //Console.WriteLine(taskData.IsComplete);
//});
//taskData.CallBack = (string res) =>
//{
// _dispatcher.Invoke(() =>
// {
// UpdateWavesFromTxt(asciiSavePath);
// _channelCount = smList.Count * 3;
// UpdateChart();
// UpdateChartData();
// });
//};
//TaskQueue.Instance.AddTaskAndRuning(taskData);
}
// else
{
if (!File.Exists(asciiSavePath))
{
MSeed2Asc(dataFilePath + dataFileName + mseedStr, asciiSavePath);
}
_dispatcher.Invoke(() =>
{
UpdateWavesFromTxt(asciiSavePath);
_channelCount = smList.Count * 3;
UpdateChart();
UpdateChartData();
});
}
}
private void UpdateChart()
{
//线程问题
LChartALL.ViewXY.YAxes = new AxisYCollection();
LChartALL.ViewXY.YAxes.Clear();
LChartALL.ViewXY.YAxes.AddRange(_wavesModel.CreateYAxisPingPu(smList, LChartALL));
for (int i = 0; i < LChartALL.ViewXY.YAxes.Count; i++)
{
LChartALL.ViewXY.YAxes[i].LabelsColor = Colors.Black;
LChartALL.ViewXY.YAxes[i].AxisColor = Colors.Black;
LChartALL.ViewXY.YAxes[i].GridStripColor = Colors.Black;
LChartALL.ViewXY.YAxes[i].Title.Color = Colors.Black;
LChartALL.ViewXY.YAxes[i].Title.Shadow.DropColor = Colors.Transparent;
LChartALL.ViewXY.YAxes[i].Title.Shadow.ContrastColor = Colors.Transparent;
}
LChartALL.ViewXY.XAxes = new AxisXCollection();
LChartALL.ViewXY.XAxes.Add(_wavesModel.GetAxisX(CurPoints / Sampling));
LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black;
LChartALL.ViewXY.SampleDataSeries = new SampleDataSeriesCollection();
LChartALL.ViewXY.SampleDataSeries.AddRange(
_wavesModel.GetSampleDataSeriesPingPu(smList, LChartALL, LChartALL.ViewXY.XAxes[0],
LChartALL.ViewXY.YAxes, _samplingFrequency));
}
private void UpdateChartData()
{
double[][] multiChannelData = new double[smList.Count * 3][];
try
{
for (int channelIndex = 0; channelIndex < smList.Count; channelIndex++)
{
multiChannelData[channelIndex * 3] = smList[channelIndex].dz.ToArray();
multiChannelData[channelIndex * 3 + 1] = smList[channelIndex].dn.ToArray();
multiChannelData[channelIndex * 3 + 2] = smList[channelIndex].de.ToArray();
}
// Invoke FeedNewDataToChart.
_dispatcher.Invoke(_chartUpdate, System.Windows.Threading.DispatcherPriority.ContextIdle,
multiChannelData as object);
}
catch (Exception ex)
{
throw ex;
}
}
public void UpdateWavesFromTxt(string fn)
{
string allStr;
smList = new List<StationModel>();
using (StreamReader streamReader = new StreamReader(fn))
{
allStr = streamReader.ReadToEnd();
}
if (allStr.Length > 0)
{
string[] strLines = allStr.Trim().Split(new char[] { '\n' });
List<string> strList = strLines.ToList();
int cnt = strList.Count;
int num = 0;
string[] snStr = strLines[0].Trim().Split(',');
string tmpName = snStr[0].Substring(14, 3);
CurPoints = int.Parse(snStr[1].Trim().Split(' ')[0]);
StationModel station = new StationModel();
station.Name = tmpName;
station.dz = new List<double>();
station.dn = new List<double>();
station.de = new List<double>();
int channelFlag = 0;
for (int i = 1; i < strLines.Length; i++)
{
string row = strLines[i].Trim();
if (strLines[i].Contains("HA"))
{
string[] rowStr = strLines[i].Split(',');
string chnStr1 = rowStr[0].Substring(21, 3);
if (chnStr1 == "SHZ")
{
smList.Add(station);
station = new StationModel();
station.Name = rowStr[0].Substring(14, 3);
channelFlag = 0;//Z
}
else if (chnStr1 == "SHN")
{
channelFlag = 1;//N
}
else
{
channelFlag = 2;//E
}
}
else
{
switch (channelFlag)
{
case 0://Z
station.dz.Add(double.Parse(row));
break;
case 1://N
station.dn.Add(double.Parse(row));
break;
case 2://E
station.de.Add(double.Parse(row));
break;
}
}
}
smList.Add(station);
smList.Reverse();
}
}
public void MSeed2Asc(string filePath, string savePath)
{
using (Process compiler = new Process())
{
compiler.StartInfo.FileName = "mseed2ascii.exe";
compiler.StartInfo.Arguments = filePath + " -o " + savePath;
compiler.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
compiler.Start();
compiler.WaitForExit();
}
}
private void ApplicationClosingDispose(object sender, CancelEventArgs e)
{
if (LChartALL != null)
{
LChartALL.Dispose();
LChartALL = null;
}
}
public void Dispose()
{
gridChart.Children.Clear();
if (LChartALL != null)
{
LChartALL.Dispose();
LChartALL = null;
}
}
public void SetWavesCombination()
{
switch (WavesCombination.Name)
{
case "平铺":
LChartCount = 1;
CreateGridChartPingPu();
break;
case "叠加":
LChartCount = 1;
CreateGridChartDieJia();
break;
case "分类":
LChartCount = 3;
CreateGridChartFenLei();
break;
}
}
public void CreateGridChartPingPu()
{
if (LChartALL != null)
{
LChartALL = null;
}
LChartALL = new LightningChart();
LChartALL.Title.Text = "事件波形";
LChartALL.Title.Color = Colors.Black;
LChartALL.Title.Shadow.DropColor = Colors.Transparent;
LChartALL.Title.Shadow.ContrastColor = Colors.Transparent;
LChartALL.Title.Font = new WpfFont("等线", 20);
LChartALL.ViewXY.AxisLayout.YAxesLayout = YAxesLayout.Stacked;
LChartALL.ViewXY.AxisLayout.SegmentsGap = 0;
LChartALL.ViewXY.ZoomPanOptions.PanDirection = PanDirection.Horizontal;
LChartALL.ViewXY.ZoomPanOptions.WheelZooming = WheelZooming.Horizontal;
//背景颜色
LChartALL.ViewXY.GraphBackground.Color = Colors.White;
LChartALL.ViewXY.GraphBackground.GradientFill = GradientFill.Solid;
LChartALL.ViewXY.GraphBackground.GradientColor = Colors.White;
LChartALL.ChartBackground.GradientFill = GradientFill.Solid;
LChartALL.ChartBackground.Color = Color.FromArgb(0, 0, 0, 0);
GridChart = new Grid();
GridChart.ColumnDefinitions.Add(new ColumnDefinition());
GridChart.Name = "chartGrid";
GridChart.Children.Add(LChartALL);
this.ChildContent = GridChart;
}
public void CreateGridChartDieJia()
{
if (LChartALL != null)
{
LChartALL = null;
}
LChartALL = new LightningChart();
LChartALL.Title.Text = "叠加";
GridChart = new Grid();
GridChart.ColumnDefinitions.Add(new ColumnDefinition());
GridChart.Name = "chartGrid";
GridChart.Children.Add(LChartALL);
this.ChildContent = GridChart;
}
public void CreateGridChartFenLei()
{
LChartZ = new LightningChart();
LChartALL.Title.Text = "Z";
LChartZ.SetValue(Grid.ColumnProperty, 0);
LChartE = new LightningChart();
LChartALL.Title.Text = "E";
LChartE.SetValue(Grid.ColumnProperty, 1);
LChartN = new LightningChart();
LChartALL.Title.Text = "N";
LChartN.SetValue(Grid.ColumnProperty, 2);
GridChart = new Grid();
GridChart.ColumnDefinitions.Add(new ColumnDefinition());
GridChart.ColumnDefinitions.Add(new ColumnDefinition());
GridChart.ColumnDefinitions.Add(new ColumnDefinition());
GridChart.Name = "chartGrid";
GridChart.Children.Add(LChartZ);
GridChart.Children.Add(LChartE);
GridChart.Children.Add(LChartN);
this.ChildContent = GridChart;
}
private void InitData()
{
LChartALL.ViewXY.YAxes = new AxisYCollection();
LChartALL.ViewXY.YAxes.Clear();
RegionNames.StationDic= RegionNames.CreateStationFromCSV(AppDomain.CurrentDomain.BaseDirectory + @"resources/N3102_staion_20230312.txt");
LChartALL.ViewXY.YAxes.AddRange(_wavesModel.CreateYAxisPingPu(RegionNames.StationDic, LChartALL));
for (int i = 0; i < LChartALL.ViewXY.YAxes.Count; i++)
{
LChartALL.ViewXY.YAxes[i].LabelsColor = Colors.Black;
LChartALL.ViewXY.YAxes[i].AxisColor = Colors.Black;
LChartALL.ViewXY.YAxes[i].GridStripColor = Colors.Black;
LChartALL.ViewXY.YAxes[i].Title.Color = Colors.Black;
LChartALL.ViewXY.YAxes[i].Title.Shadow.DropColor = Colors.Transparent;
LChartALL.ViewXY.YAxes[i].Title.Shadow.ContrastColor = Colors.Transparent;
LChartALL.ViewXY.YAxes[i].Title.Font = new WpfFont("Calibri", 12);
}
LChartALL.ViewXY.XAxes = new AxisXCollection();
LChartALL.ViewXY.XAxes.Add(_wavesModel.GetAxisX(CurPoints / Sampling));
LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black;
LChartALL.ViewXY.SampleDataSeries = new SampleDataSeriesCollection();
LChartALL.ViewXY.SampleDataSeries.AddRange(
_wavesModel.GetSampleDataSeriesPingPu(RegionNames.StationDic, LChartALL, LChartALL.ViewXY.XAxes[0],
LChartALL.ViewXY.YAxes, _samplingFrequency));
//string mseedPath = FileDataPath + "\\" + StartTime.Year.ToString("D2");
//Console.WriteLine(mseedPath);
//Start();
}
private void FeedNewDataToChartPingPu(double[][] data)
{
LChartALL.BeginUpdate();
for (int channelIndex = 0; channelIndex < _channelCount; channelIndex++)
{
LChartALL.ViewXY.SampleDataSeries[channelIndex].AddSamples(data[channelIndex], true);
//LChartALL.ViewXY.YAxes[channelIndex].Minimum = data[channelIndex].Min();
//LChartALL.ViewXY.YAxes[channelIndex].Maximum = data[channelIndex].Max();
}
_previousX = (double)_samplesOutput / _samplingFrequency;
LChartALL.ViewXY.XAxes[0].ScrollPosition = _previousX;
LChartALL.EndUpdate();
}
}
/// <summary>
/// 波形组合
/// </summary>
public enum WavesCombinationEnum
{
= 0,
,
}
/// <summary>
/// 波形类型
/// </summary>
public enum DataTypeEnum
{
= 0,
}
/// <summary>
/// 数据来源
/// </summary>
public enum DataSourcesEnum
{
= 0,
}
/// <summary>
/// 显示模式
/// </summary>
public enum DisplayModeEnum
{
= 0,
}
public enum ScollModeEnum
{
Scrolling = 0,
Stepping
}
}