diff --git a/Txgy.EWS.Client.PageModule/ViewModels/ReportViewModel.cs b/Txgy.EWS.Client.PageModule/ViewModels/ReportViewModel.cs
index 63f8ea5..28e3ffc 100644
--- a/Txgy.EWS.Client.PageModule/ViewModels/ReportViewModel.cs
+++ b/Txgy.EWS.Client.PageModule/ViewModels/ReportViewModel.cs
@@ -80,7 +80,18 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
public int CompletedCount { get; set; }
public int TotalCount { get; set; }
public string Message { get; set; }
+ public double? Percent { get; set; }
+ public bool IsIndeterminate { get; set; }
+ public bool ShowCount { get; set; }
}
+
+ private const double SearchProgressQueryComplete = 5;
+ private const double SearchProgressComputeComplete = 80;
+ private const double SearchProgressListComplete = 84;
+ private const double SearchProgressEnergyComplete = 87;
+ private const double SearchProgressDayFreqComplete = 90;
+ private const double SearchProgressPlanComplete = 95;
+ private const double SearchProgressComplete = 100;
///
/// 查询模式:0:自定义查询;1:日报;2:周报;3:月报
///
@@ -444,7 +455,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
ResetSearchProgress("正在查询事件数据...");
var progress = new Progress(UpdateSearchProgress);
var results = await SearchEventsAsync(st, et, progress);
- ApplySearchResults(rView, results, st, createDayFreq);
+ await ApplySearchResultsAsync(rView, results, st, createDayFreq, progress);
}
catch (Exception ex)
{
@@ -456,33 +467,78 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
}
}
- private void ApplySearchResults(ReportView rView, List results, DateTime st, bool createDayFreq)
+ private async Task ApplySearchResultsAsync(ReportView rView, List results, DateTime st, bool createDayFreq, IProgress progress)
{
if (results == null)
{
return;
}
- SelectResult = new ObservableCollection(results);
- SearchCount = results.Count;
+ await RefreshResultListAsync(results, progress);
+ progress.Report(CreateStageProgress("正在统计能量", SearchProgressListComplete));
+ await YieldToUiAsync();
UpdateEnergyStats(results);
if (createDayFreq)
{
+ progress.Report(CreateStageProgress("正在生成频度图", SearchProgressEnergyComplete));
+ await YieldToUiAsync();
FreqChart = CreateDayFreqImage(results, st, st.ToString("D", culture));
}
+ progress.Report(CreateStageProgress("正在筛选中等能量事件", SearchProgressDayFreqComplete));
+ await YieldToUiAsync();
var mes = results.Where(rs => rs.Energy >= MiddleEnergy).ToList();
MiddleEnergyEvents = mes;
MiddleEventCount = mes.Count();
if (mes.Count > 0 && rView != null)
{
+ progress.Report(CreateStageProgress("正在绘制平面图", SearchProgressDayFreqComplete));
+ await YieldToUiAsync();
ReportPlanImage rpi = new ReportPlanImage();
rpi.Draw(mes, rView.canvasPlan.ActualWidth, rView.canvasPlan.ActualHeight);
rView.canvasPlan.Children.Clear();
rView.canvasPlan.Children.Add(rpi.host);
+ progress.Report(CreateStageProgress("正在生成三维图", SearchProgressPlanComplete));
+ await YieldToUiAsync();
CreateStereoChart(mes);
}
+ progress.Report(CreateStageProgress("查询完成", SearchProgressComplete));
+ await YieldToUiAsync();
+ }
+
+ private async Task RefreshResultListAsync(List results, IProgress progress)
+ {
+ SelectResult = new ObservableCollection();
+ SearchCount = results.Count;
+
+ if (results.Count == 0)
+ {
+ progress.Report(CreateStageProgress("正在刷新事件列表", SearchProgressListComplete));
+ await YieldToUiAsync();
+ return;
+ }
+
+ const int batchSize = 50;
+ for (int i = 0; i < results.Count; i++)
+ {
+ SelectResult.Add(results[i]);
+ if ((i + 1) % batchSize == 0 || i == results.Count - 1)
+ {
+ double percent = SearchProgressComputeComplete
+ + ((i + 1) / (double)results.Count) * (SearchProgressListComplete - SearchProgressComputeComplete);
+ progress.Report(new SearchProgressInfo
+ {
+ CompletedCount = i + 1,
+ TotalCount = results.Count,
+ Message = "正在刷新事件列表",
+ Percent = percent,
+ IsIndeterminate = false,
+ ShowCount = true
+ });
+ await YieldToUiAsync();
+ }
+ }
}
private void ResetSearchProgress(string message)
@@ -500,9 +556,23 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
return;
}
+ if (progress.Percent.HasValue)
+ {
+ double explicitPercent = Math.Max(0, Math.Min(100, progress.Percent.Value));
+ SearchProgressIndeterminate = progress.IsIndeterminate;
+ SearchProgressValue = explicitPercent;
+ SearchProgressPercentText = progress.IsIndeterminate ? "" : explicitPercent.ToString("F0") + "%";
+ SearchProgressText = BuildSearchProgressText(progress);
+ if (progress.TotalCount > 0)
+ {
+ SearchCount = progress.TotalCount;
+ }
+ return;
+ }
+
if (progress.TotalCount <= 0)
{
- SearchProgressIndeterminate = progress.Message != "未查询到事件";
+ SearchProgressIndeterminate = progress.IsIndeterminate || progress.Message != "未查询到事件";
SearchProgressValue = 0;
SearchProgressPercentText = progress.Message == "未查询到事件" ? "0%" : "";
SearchProgressText = progress.Message;
@@ -518,7 +588,65 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
SearchProgressIndeterminate = false;
SearchProgressValue = percent;
SearchProgressPercentText = percent.ToString("F0") + "%";
- SearchProgressText = progress.Message + " " + progress.CompletedCount + "/" + progress.TotalCount;
+ SearchProgressText = BuildSearchProgressText(progress);
+ }
+
+ private string BuildSearchProgressText(SearchProgressInfo progress)
+ {
+ if (progress.ShowCount && progress.TotalCount > 0)
+ {
+ return progress.Message + " " + progress.CompletedCount + "/" + progress.TotalCount;
+ }
+ return progress.Message;
+ }
+
+ private SearchProgressInfo CreateStageProgress(string message, double percent, bool isIndeterminate = false)
+ {
+ return new SearchProgressInfo
+ {
+ CompletedCount = 0,
+ TotalCount = 0,
+ Message = message,
+ Percent = percent,
+ IsIndeterminate = isIndeterminate,
+ ShowCount = false
+ };
+ }
+
+ private SearchProgressInfo CreateEventProgress(int completedCount, int totalCount, int stageIndex, int stageCount, string message)
+ {
+ if (totalCount <= 0)
+ {
+ return CreateStageProgress(message, SearchProgressQueryComplete);
+ }
+
+ int safeStageIndex = Math.Max(0, Math.Min(stageIndex, stageCount));
+ double eventProgress = (completedCount + safeStageIndex / (double)stageCount) / totalCount;
+ double percent = SearchProgressQueryComplete + eventProgress * (SearchProgressComputeComplete - SearchProgressQueryComplete);
+ int displayCount = Math.Min(completedCount + 1, totalCount);
+
+ return new SearchProgressInfo
+ {
+ CompletedCount = displayCount,
+ TotalCount = totalCount,
+ Message = message,
+ Percent = percent,
+ IsIndeterminate = false,
+ ShowCount = true
+ };
+ }
+
+ private void ReportSearchProgress(IProgress progress, SearchProgressInfo progressInfo)
+ {
+ if (progress != null)
+ {
+ progress.Report(progressInfo);
+ }
+ }
+
+ private static async Task YieldToUiAsync()
+ {
+ await Task.Delay(1);
}
///
@@ -707,7 +835,7 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
}
private Task> SearchEventsAsync(DateTime searchStartTime, DateTime searchEndTime, IProgress progress)
{
- return Task.Run(() => SearchEventsCore(searchStartTime, searchEndTime, progress));
+ return SearchEventsCoreAsync(searchStartTime, searchEndTime, progress);
}
public List SearchEvents(DateTime searchStartTime, DateTime searchEndTime)
@@ -719,6 +847,11 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
}
private List SearchEventsCore(DateTime searchStartTime, DateTime searchEndTime, IProgress progress)
+ {
+ return SearchEventsCoreAsync(searchStartTime, searchEndTime, progress).GetAwaiter().GetResult();
+ }
+
+ private async Task> SearchEventsCoreAsync(DateTime searchStartTime, DateTime searchEndTime, IProgress progress)
{
List results = new List();
string findStr = "select * from " + GlobalConfig.UseResultTable;
@@ -761,30 +894,21 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
}
if (progress != null)
{
- progress.Report(new SearchProgressInfo
- {
- CompletedCount = 0,
- TotalCount = 0,
- Message = "正在查询事件数据..."
- });
+ progress.Report(CreateStageProgress("正在查询事件数据...", 0, true));
}
- var list = fsqlTencent.Select()
- .WithSql(findStr).ToList();
+ var list = await Task.Run(() => fsqlTencent.Select()
+ .WithSql(findStr).ToList()).ConfigureAwait(false);
int totalCount = list == null ? 0 : list.Count;
- if (progress != null)
- {
- progress.Report(new SearchProgressInfo
- {
- CompletedCount = 0,
- TotalCount = totalCount,
- Message = totalCount == 0 ? "未查询到事件" : "正在计算震源机制"
- });
- }
+ ReportSearchProgress(progress, totalCount == 0
+ ? CreateStageProgress("未查询到事件", 0)
+ : CreateEventProgress(0, totalCount, 0, 4, "正在准备事件"));
if (list != null)
{
int completedCount = 0;
+ const int eventStageCount = 4;
foreach (var item in list)
{
+ ReportSearchProgress(progress, CreateEventProgress(completedCount, totalCount, 0, eventStageCount, "正在准备事件"));
GridItemEventResult se = new GridItemEventResult(item, true);
string eventTimeStr = se.EventTime;
string datePath = eventTimeStr.Substring(0, 4) + eventTimeStr.Substring(5, 2) + eventTimeStr.Substring(8, 2);
@@ -793,39 +917,49 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
+ eventTimeStr.Substring(8, 2) + eventTimeStr.Substring(10, 3)
+ eventTimeStr.Substring(14, 2) + eventTimeStr.Substring(17, 2) + ".01" + GlobalConfig.DataTypeString;
string jsonStr = ".json";
+ string jsonFilePath = dataFilePath + dataFileName + jsonStr;
MmEvent curMmEvent = new MmEvent();
curMmEvent.EventTimeStr = eventTimeStr;
curMmEvent.X = se.X;
curMmEvent.Y = se.Y;
curMmEvent.RMS = se.RMS;
curMmEvent.DominantFreq = 15;
+ bool canComputeWaveform = false;
//查询事件Json文件是否已下载
- if (File.Exists(dataFilePath + dataFileName + jsonStr))
+ if (File.Exists(jsonFilePath))
{
- FileInfo fileInfo = new FileInfo(dataFilePath + dataFileName + jsonStr);
+ FileInfo fileInfo = new FileInfo(jsonFilePath);
if (fileInfo.Length > 1024)
{
- ComputeFM(curMmEvent);
- //目前提取的为半周期
- curMmEvent.DominantFreq = GlobalData.GetDominFreq(eventTimeStr);
+ canComputeWaveform = true;
}
}
else
{
#region 同步方式
- int res = new DownloadJsonFile().Download(eventTimeStr, dataFilePath, dataFileName + jsonStr, GlobalConfig.UseWaveDataTable);
+ ReportSearchProgress(progress, CreateEventProgress(completedCount, totalCount, 1, eventStageCount, "正在下载波形JSON"));
+ int res = await DownloadJsonFile.DownloadAsync(eventTimeStr, dataFilePath, dataFileName + jsonStr, GlobalConfig.UseWaveDataTable).ConfigureAwait(false);
if (res > -1)
{
- FileInfo fileInfo2 = new FileInfo(dataFilePath + dataFileName + jsonStr);
+ FileInfo fileInfo2 = new FileInfo(jsonFilePath);
if (fileInfo2.Length > 2000)
{
- ComputeFM(curMmEvent);
- //目前提取的为半周期
- curMmEvent.DominantFreq = GlobalData.GetDominFreq(eventTimeStr);
+ canComputeWaveform = true;
}
}
#endregion
}
+
+ if (canComputeWaveform)
+ {
+ ReportSearchProgress(progress, CreateEventProgress(completedCount, totalCount, 1, eventStageCount, "正在读取波形JSON"));
+ JObject eventJson = ReadEventJsonRoot(jsonFilePath);
+ ReportSearchProgress(progress, CreateEventProgress(completedCount, totalCount, 2, eventStageCount, "正在计算震源机制"));
+ ComputeFM(curMmEvent, eventJson, jsonFilePath);
+ ReportSearchProgress(progress, CreateEventProgress(completedCount, totalCount, 3, eventStageCount, "正在计算主频"));
+ //目前提取的为半周期
+ curMmEvent.DominantFreq = GetDominFreq(eventJson);
+ }
Random dominRnd = new Random((int)DateTime.Parse(curMmEvent.EventTimeStr).Ticks);
int dominFreq = (int)curMmEvent.DominantFreq;
@@ -838,16 +972,8 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
se.Direction = curMmEvent.Direction;
se.SetEnergy();
results.Add(se);
+ ReportSearchProgress(progress, CreateEventProgress(completedCount, totalCount, eventStageCount, eventStageCount, "正在整理事件结果"));
completedCount++;
- if (progress != null)
- {
- progress.Report(new SearchProgressInfo
- {
- CompletedCount = completedCount,
- TotalCount = totalCount,
- Message = "正在计算震源机制"
- });
- }
}
}
return results;
@@ -867,6 +993,41 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
AverageEnergy = Math.Round(results.Average(rs => rs.Energy), 2);
MaxEnergy = Math.Round(results.Max(rs => rs.Energy), 2);
}
+
+ private JObject ReadEventJsonRoot(string jsonFilePath)
+ {
+ using (StreamReader sr = System.IO.File.OpenText(jsonFilePath))
+ {
+ JsonTextReader reader = new JsonTextReader(sr);
+ JArray jArray = (JArray)JToken.ReadFrom(reader);
+ return (JObject)jArray[0];
+ }
+ }
+
+ private int GetDominFreq(JObject eventJson)
+ {
+ int dominantFreq = 0;
+ List dominantFreqList = new List();
+ JArray phaseArr = JArray.FromObject(eventJson["phases"]);
+ for (int i = 0; i < phaseArr.Count; i++)
+ {
+ if (phaseArr[i]["zcr"] != null)
+ {
+ dominantFreqList.Add(double.Parse(phaseArr[i]["zcr"].ToString()));
+ }
+ }
+
+ if (dominantFreqList.Count > 3)
+ {
+ double min = dominantFreqList.Min();
+ double max = dominantFreqList.Max();
+ dominantFreqList.Remove(min);
+ dominantFreqList.Remove(max);
+ dominantFreq = (int)(dominantFreqList.Sum() / dominantFreqList.Count);
+ }
+
+ return dominantFreq;
+ }
public void ExportEventListReport(ReportView rView)
{
@@ -1350,6 +1511,30 @@ namespace Txgy.EWS.Client.PageModule.ViewModels
mmEvent.FocalType = cr.FocalType;
mmEvent.Direction = cr.Direction;
}
+
+ public void ComputeFM(MmEvent mmEvent, JObject eventJson, string jsonFilePath)
+ {
+ mmEvent.JsonFile = jsonFilePath;
+ mmEvent.SetEnergy();
+ mmEvent.Phases = new Dictionary();
+ JArray phaseArr = JArray.FromObject(eventJson["phases"]);
+ for (int i = 0; i < phaseArr.Count; i++)
+ {
+ if (phaseArr[i]["first_motion_direct"] != null)
+ {
+ mmEvent.Phases.Add(phaseArr[i]["id"].ToString().Substring(3, 3),
+ int.Parse(phaseArr[i]["first_motion_direct"].ToString()));
+ }
+ }
+
+ FMMap fmMap = CreateFM(mmEvent, GlobalConfig.ProjectConfig.WorkArea.EMin, GlobalConfig.ProjectConfig.WorkArea.NMin);
+ ComputationResult cr = GlobalConfig.fmCore.ComputeResult(fmMap);
+ if (cr == null)
+ return;
+ mmEvent.FocalType = cr.FocalType;
+ mmEvent.Direction = cr.Direction;
+ }
+
public FMMap CreateFM(MmEvent mmEvent, double BaseX, double BaseY)
{
FMMap fmMap = new FMMap();