|
|
|
@ -34,12 +34,14 @@ using System.Windows.Threading;
|
|
|
|
|
using System.Xml.Linq;
|
|
|
|
|
using Prism.Regions;
|
|
|
|
|
using static System.Collections.Specialized.BitVector32;
|
|
|
|
|
using System.Net.NetworkInformation;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
|
|
|
|
namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
{
|
|
|
|
|
public class ChartPlotViewModel : BindableBase, INavigationAware
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
Mseed2asciiApi.LoopCallbackHandler loopCallback;
|
|
|
|
|
public ChartPlotViewModel()
|
|
|
|
|
{
|
|
|
|
|
_dispatcher = Application.Current.Dispatcher;
|
|
|
|
@ -47,7 +49,77 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
(Application.Current.MainWindow as System.Windows.Window).Closing += ApplicationClosingDispose;
|
|
|
|
|
IntervalTime=100;
|
|
|
|
|
CreateChart();
|
|
|
|
|
loopCallback = new Mseed2asciiApi.LoopCallbackHandler(Mseed2AsciiEvent);
|
|
|
|
|
GC.KeepAlive(loopCallback);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
private void Mseed2AsciiEvent(AsciiDataStruct asciiData)
|
|
|
|
|
{
|
|
|
|
|
DateTime startTime = Convert.ToDateTime(asciiData.starttime).AddHours(8);
|
|
|
|
|
DateTime endTime = Convert.ToDateTime(asciiData.endtime).AddHours(8);
|
|
|
|
|
byte[] bytes = new byte[asciiData.numsamples * asciiData.samplesize];
|
|
|
|
|
// IntPtr bufferHandler = Marshal.AllocHGlobal((int)asciiData.datasize);
|
|
|
|
|
Marshal.Copy(asciiData.datasamples, bytes, 0, bytes.Length);
|
|
|
|
|
List<double> lines = new List<double>();
|
|
|
|
|
string[] sid = asciiData.sid.Substring(5).Split('_');
|
|
|
|
|
string name = $"{sid[0]}.{sid[1]}.{sid[2]}.{sid[3]}{sid[4]}{sid[5]}";
|
|
|
|
|
var ts = DateTime.Now.Subtract(startTime);
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"台站号:{name},总数:{asciiData.samprate},{asciiData.datasize},{asciiData.samplecnt}, {asciiData.numsamples},当前时间:{DateTime.Now.ToString("o")},接时间:{startTime.ToString("o")}********时间差:{ts.TotalSeconds}秒");
|
|
|
|
|
//if (ts.TotalSeconds > 20)
|
|
|
|
|
//{
|
|
|
|
|
// return;
|
|
|
|
|
//}
|
|
|
|
|
if (asciiData.sampletype == 'i')
|
|
|
|
|
{
|
|
|
|
|
for (int index = 0; index < bytes.Length; index += 4)
|
|
|
|
|
{
|
|
|
|
|
var a = BitConverter.ToInt32(bytes, index);
|
|
|
|
|
lines.Add(a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (asciiData.sampletype == 'f')
|
|
|
|
|
{
|
|
|
|
|
for (int index = 0; index < bytes.Length; index += 4)
|
|
|
|
|
{
|
|
|
|
|
var b = BitConverter.ToSingle(bytes, index);
|
|
|
|
|
lines.Add(b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (asciiData.sampletype == 'd')
|
|
|
|
|
{
|
|
|
|
|
for (int index = 0; index < bytes.Length; index += 8)
|
|
|
|
|
{
|
|
|
|
|
var b = BitConverter.ToDouble(bytes, index);
|
|
|
|
|
lines.Add(b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dat = smList.Where(p => p.Name == sid[1]).FirstOrDefault();
|
|
|
|
|
var channelFlag = ($"{sid[3]}{sid[4]}{sid[5]}" == "SHZ") ? 0 : ($"{sid[3]}{sid[4]}{sid[5]}" == "SHN") ? 1 : 2;
|
|
|
|
|
if (dat == null)
|
|
|
|
|
{
|
|
|
|
|
StationModel station = new StationModel
|
|
|
|
|
{
|
|
|
|
|
Name = sid[1],
|
|
|
|
|
BeginTime = startTime,
|
|
|
|
|
PointCount = (int)asciiData.numsamples,
|
|
|
|
|
SamplingFrequency = (int)asciiData.samprate,
|
|
|
|
|
};
|
|
|
|
|
smList.Enqueue(station);
|
|
|
|
|
dat = station;
|
|
|
|
|
}
|
|
|
|
|
switch (channelFlag)
|
|
|
|
|
{
|
|
|
|
|
case 0://Z
|
|
|
|
|
dat.dz.AddRange(lines);
|
|
|
|
|
break;
|
|
|
|
|
case 1://N
|
|
|
|
|
dat.dn.AddRange(lines);
|
|
|
|
|
break;
|
|
|
|
|
case 2://E
|
|
|
|
|
dat.de.AddRange(lines);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 字段
|
|
|
|
@ -244,17 +316,21 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
|
|
|
|
|
#region 事件
|
|
|
|
|
public DelegateCommand LoadedCommand => new DelegateCommand(Loaded);
|
|
|
|
|
public DelegateCommand UnloadedCommand => new DelegateCommand(UnLoaded);
|
|
|
|
|
public DelegateCommand<object> AxesYVisibleCommand => new DelegateCommand<object>(AxesYVisible);
|
|
|
|
|
public DelegateCommand<object> FileSelectorCommand => new DelegateCommand<object>(FileSelector);
|
|
|
|
|
public DelegateCommand<object> OtimeSortCommand => new DelegateCommand<object>(OtimeSort);
|
|
|
|
|
public DelegateCommand IntervalSureCommand => new DelegateCommand(IntervalSure);
|
|
|
|
|
public DelegateCommand<object> RealTimeDataCommand => new DelegateCommand<object>(RealTimeData);
|
|
|
|
|
|
|
|
|
|
private void Loaded()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
Mseed2asciiApi.MseedDatasCallFun(loopCallback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UnLoaded()
|
|
|
|
|
{
|
|
|
|
|
Mseed2asciiApi.MseedDatasCallFun(null);
|
|
|
|
|
}
|
|
|
|
|
private void AxesYVisible(object isCheck)
|
|
|
|
|
{
|
|
|
|
|
if (_lChartAll != null)
|
|
|
|
@ -281,14 +357,18 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
if (openFileDialog.ShowDialog() == true)
|
|
|
|
|
{
|
|
|
|
|
string asciiSavePath = openFileDialog.FileName.Replace("Mseed", "Txt");
|
|
|
|
|
asciiSavePath = Path.ChangeExtension(asciiSavePath, ".txt");
|
|
|
|
|
string JsonPath = Path.ChangeExtension(openFileDialog.FileName, "Json");
|
|
|
|
|
asciiSavePath = Path.ChangeExtension(asciiSavePath, "txt");
|
|
|
|
|
string JsonPath = Path.ChangeExtension(openFileDialog.FileName, "json");
|
|
|
|
|
if(!File.Exists(JsonPath))
|
|
|
|
|
{
|
|
|
|
|
JsonPath = JsonPath.Replace(".json", "B.json");
|
|
|
|
|
}
|
|
|
|
|
Stopwatch st = new Stopwatch();
|
|
|
|
|
st.Start();
|
|
|
|
|
//读取.json文件
|
|
|
|
|
CurrentEventTime = _wavesModel.ReadChartJsonFile(JsonPath);
|
|
|
|
|
//读取.mseed文件
|
|
|
|
|
smList = _wavesModel.ReadMseedFile(openFileDialog.FileName, asciiSavePath, IsMultFiles);
|
|
|
|
|
_wavesModel.ReadMseedFile(openFileDialog.FileName, asciiSavePath, IsMultFiles);
|
|
|
|
|
_channelCount = smList.Count * 3;
|
|
|
|
|
CurrentTime = smList.First().BeginTime.ToShortDateString();
|
|
|
|
|
StationsName = smList.Select(a => new StationAxis{Name= a.Name,IsChecked=true,SelectCommand =new DelegateCommand<object>(StationsNameVisible)}).ToList();
|
|
|
|
@ -461,48 +541,6 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
_lChartAll.EndUpdate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RealTimeData(object isCheck)
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
String str = "N02,N03,N04,N05,N06";//,N07,N08,N09,N10,N11,N12,N13,N14,N15,N16,N17,N18,N19,N20,N21,N22,N23,N24,N25,N26,N27";
|
|
|
|
|
var stations= str.Split(',');
|
|
|
|
|
smList = _wavesModel.ReadWavesFromJson(stations);
|
|
|
|
|
_channelCount = smList.Count * 3;
|
|
|
|
|
CurrentTime = smList.First().BeginTime.ToShortDateString();
|
|
|
|
|
StationsName = smList.Select(a => new StationAxis { Name = a.Name, IsChecked = true, SelectCommand = new DelegateCommand<object>(StationsNameVisible) }).ToList();
|
|
|
|
|
// StartChart();
|
|
|
|
|
|
|
|
|
|
if (_lChartAll != null)
|
|
|
|
|
{
|
|
|
|
|
bool isStartRealData = (Convert.ToBoolean(isCheck) == true);
|
|
|
|
|
if (smList.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_lChartAll.BeginUpdate();
|
|
|
|
|
if (isStartRealData)
|
|
|
|
|
{
|
|
|
|
|
StartChart();
|
|
|
|
|
//Set real-time monitoring automatic old data destruction
|
|
|
|
|
LChartALL.ViewXY.DropOldSeriesData = true;
|
|
|
|
|
_pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum;
|
|
|
|
|
dispatcherTimer.Tick -= CompositionTarget_Rendering;
|
|
|
|
|
dispatcherTimer.Tick += CompositionTarget_Rendering;
|
|
|
|
|
LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Scrolling;
|
|
|
|
|
dispatcherTimer.Start();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dispatcherTimer.Stop();
|
|
|
|
|
|
|
|
|
|
LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.None;
|
|
|
|
|
dispatcherTimer.Tick -= CompositionTarget_Rendering;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_lChartAll.EndUpdate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
private void CreateChart()
|
|
|
|
|
{
|
|
|
|
@ -701,6 +739,9 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
LChartALL.BeginUpdate();
|
|
|
|
|
for (int channelIndex = 0; channelIndex < _channelCount; channelIndex++)
|
|
|
|
|
{
|
|
|
|
|
double[] thisSeriesData = _data[channelIndex];
|
|
|
|
|
_lChartAll.ViewXY.YAxes[channelIndex].SetRange(thisSeriesData.Min() - 1, thisSeriesData.Max() + 1);
|
|
|
|
|
|
|
|
|
|
LChartALL.ViewXY.SampleDataSeries[channelIndex].AddSamples(_data[channelIndex], true);
|
|
|
|
|
}
|
|
|
|
|
LChartALL.EndUpdate();
|
|
|
|
@ -750,100 +791,11 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 实时数据
|
|
|
|
|
private void CompositionTarget_Rendering(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
RenderNextFrame();
|
|
|
|
|
}
|
|
|
|
|
private void RenderNextFrame()
|
|
|
|
|
{
|
|
|
|
|
if (_lChartAll == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_dispatcher.Invoke(() =>
|
|
|
|
|
{
|
|
|
|
|
FeedData(/*chartTitleText*/);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
int _iRound = 0;
|
|
|
|
|
double _pointsAppended = 0;
|
|
|
|
|
double[][] _data;
|
|
|
|
|
int PreGenerateDataForRoundCount = 6;
|
|
|
|
|
private void FeedData(/*string chartTitleText*/)
|
|
|
|
|
{
|
|
|
|
|
if (_lChartAll != null)
|
|
|
|
|
{
|
|
|
|
|
_lChartAll.BeginUpdate();
|
|
|
|
|
|
|
|
|
|
//Append data to series
|
|
|
|
|
System.Threading.Tasks.Parallel.For(0, _channelCount, (seriesIndex) =>
|
|
|
|
|
{
|
|
|
|
|
double[] thisSeriesData = _data[seriesIndex];
|
|
|
|
|
double[] dataToAppendNow = new double[_samplingFrequency];
|
|
|
|
|
Array.Copy(thisSeriesData, (_iRound % PreGenerateDataForRoundCount) * _samplingFrequency, dataToAppendNow, 0, _samplingFrequency);
|
|
|
|
|
_lChartAll.ViewXY.SampleDataSeries[seriesIndex].AddSamples(dataToAppendNow, false);
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("***********index:{0}, pointCount:{1},time:{2}", seriesIndex,
|
|
|
|
|
_lChartAll.ViewXY.SampleDataSeries[seriesIndex].PointCount, DateTime.Now);
|
|
|
|
|
});
|
|
|
|
|
_pointsAppended += 1;
|
|
|
|
|
|
|
|
|
|
//Set X axis real-time scrolling position
|
|
|
|
|
double lastX = _pointsAppended;
|
|
|
|
|
_lChartAll.ViewXY.XAxes[0].ScrollPosition = lastX;
|
|
|
|
|
|
|
|
|
|
//Update sweep bands
|
|
|
|
|
if (_lChartAll.ViewXY.XAxes[0].ScrollMode == XAxisScrollMode.Sweeping)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//Dark band of old page fading away
|
|
|
|
|
double pageLen = _lChartAll.ViewXY.XAxes[0].Maximum - _lChartAll.ViewXY.XAxes[0].Minimum;
|
|
|
|
|
double sweepGapWidth = pageLen / 20.0;
|
|
|
|
|
_lChartAll.ViewXY.Bands[0].SetValues(lastX - pageLen, lastX - pageLen + sweepGapWidth);
|
|
|
|
|
if (_lChartAll.ViewXY.Bands[0].Visible == false)
|
|
|
|
|
{
|
|
|
|
|
_lChartAll.ViewXY.Bands[0].Visible = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Bright new page band
|
|
|
|
|
_lChartAll.ViewXY.Bands[1].SetValues(lastX - sweepGapWidth / 6, lastX);
|
|
|
|
|
if (_lChartAll.ViewXY.Bands[1].Visible == false)
|
|
|
|
|
{
|
|
|
|
|
_lChartAll.ViewXY.Bands[1].Visible = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Hide sweeping bands if not in sweeping mode
|
|
|
|
|
//if (_lChartAll.ViewXY.Bands[0].Visible == true)
|
|
|
|
|
//{
|
|
|
|
|
// _lChartAll.ViewXY.Bands[0].Visible = false;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//if (_lChartAll.ViewXY.Bands[1].Visible == true)
|
|
|
|
|
//{
|
|
|
|
|
// _lChartAll.ViewXY.Bands[1].Visible = false;
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
_lChartAll.EndUpdate();
|
|
|
|
|
|
|
|
|
|
_iRound++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private double[][] _data;
|
|
|
|
|
|
|
|
|
|
public void OnNavigatedTo(NavigationContext navigationContext)
|
|
|
|
|
{
|
|
|
|
|
var str= navigationContext.Parameters.GetValue<string>("model");
|
|
|
|
|
if(str == "实时波形")
|
|
|
|
|
{
|
|
|
|
|
IsRealtimeData = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
IsRealtimeData = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsNavigationTarget(NavigationContext navigationContext)
|
|
|
|
@ -855,7 +807,5 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|