using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Misc;
using System.Data;
using System.Xml;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;
using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
namespace FLY.Thick.Base.Server
{
public class BoltMapImg : IBoltMapService, INotifyPropertyChanged, Misc.ISaveToXml, IBoltMapBase
{
#region 成员变量
#region 数据文件需要保存的数据项
private int _firstBoltNo;
///
/// 1st 分区号,之后的不断加1
///
public int FirstBoltNo
{
get { return _firstBoltNo; }
set {
_firstBoltNo = value;
NotifyPropertyChanged("FirstBoltNo");
}
}
private BORDER_TYPE bordertype;
///
/// 找边界,边界类型
///
public BORDER_TYPE BorderType
{
get { return bordertype; }
set {
if (bordertype != value)
{
bordertype = value;
NotifyPropertyChanged("BorderType");
}
}
}
private int borderboltno_b;
///
/// 开始边界分区号
///
public int BorderBoltNo_B
{
get { return borderboltno_b; }
set
{
if (borderboltno_b != value)
{
borderboltno_b = value;
NotifyPropertyChanged("BorderBoltNo_B");
}
}
}
private int borderboltno_e;
///
/// 结束边界分区号
///
public int BorderBoltNo_E
{
get { return borderboltno_e; }
set
{
if (borderboltno_e != value)
{
borderboltno_e = value;
NotifyPropertyChanged("BorderBoltNo_E");
}
}
}
public ObservableCollection _bolts = new ObservableCollection();
public ObservableCollection Bolts
{
get
{
return _bolts;
}
}
private int smooth;
public int Smooth
{
get { return smooth; }
set {
if (smooth != value)
{
smooth = value;
NotifyPropertyChanged("Smooth");
}
}
}
#endregion
#region 只用于描述 Bolts,没什么用
private int lastboltno;
///
/// 最后一个分区号
///
public int LastBoltNo {
get {
return lastboltno;
}
protected set
{
if (lastboltno != value)
{
lastboltno = value;
NotifyPropertyChanged("LastBoltNo");
}
}
}
private int boltinterval;
///
/// 平均分区间隔
///
public int BoltInterval {
get
{
return boltinterval;
}
set {
if (boltinterval != value)
{
boltinterval = value;
NotifyPropertyChanged("BoltInterval");
}
}
}
private int boltwidth;
///
/// 平均分区宽度
///
public int BoltWidth {
get {
return boltwidth;
}
protected set {
if (boltwidth != value)
{
boltwidth = value;
NotifyPropertyChanged("BoltWidth");
}
}
}
private int posbegin;
///
/// 脉冲范围 开始
///
public int PosBegin {
get {
return posbegin;
}
protected set {
if (posbegin != value)
{
posbegin = value;
NotifyPropertyChanged("PosBegin");
}
}
}
private int posend;
///
/// 脉冲范围 结束
///
public int PosEnd {
get {
return posend;
}
protected set {
if (posend != value)
{
posend = value;
NotifyPropertyChanged("PosEnd");
}
}
}
#endregion
#endregion
///
/// 动态分区
///
private DynBoltAD dyn;
private BoltMapHelper helper;
public event ActiveEventHandler ActiveEvent;
public BoltMapImg()
{
dyn = new DynBoltAD(this);
helper = new BoltMapHelper(this);
}
public BoltMapImg(string param_path)
{
if (!string.IsNullOrEmpty(param_path))
Path = param_path;
else
Path = "boltmap.xml";
//设置默认值----------------------------------------------------------------
EasyCreate(1, 50, 9000);
//-------------------------------------------------------------------------------
if (!Load(null))
{
}
apply2();
}
static BoltMapImg()
{
Misc.SaveToXmlHepler.Regist(typeof(BoltMapImg));
}
private void apply2()
{
LastBoltNo = FirstBoltNo + Bolts.Count() - 1;
PosBegin = Bolts.First().Begin;
PosEnd = Bolts.Last().End;
BoltWidth = (int)Bolts.Average((r) => r.Width);
List buf = new List();
for (int i = 1; i < Bolts.Count(); i++)
{
int interval = Bolts[i].Mid - Bolts[i - 1].Mid;
buf.Add(interval);
}
BoltInterval = (int)buf.Average();
//检测 膜边界参数
if (BorderBoltNo_B < FirstBoltNo)
BorderBoltNo_B = FirstBoltNo;
if (BorderBoltNo_E > LastBoltNo)
BorderBoltNo_E = LastBoltNo;
if (BorderBoltNo_B > BorderBoltNo_E)
{
BorderBoltNo_B = FirstBoltNo;
BorderBoltNo_E = LastBoltNo;
}
}
public void Apply()
{
apply2();
Save(null);
//触发事件!!!!
//TODO
if (ActiveEvent != null)
ActiveEvent(this);
}
public void ApplyWithoutSave()
{
apply2();
//触发事件!!!!
//TODO
if (ActiveEvent != null)
ActiveEvent(this);
}
public void ApplyBorder()
{
Save(null);
}
public void Clear()
{
Bolts.Clear();
}
public int NBolts
{
get
{
return Bolts.Count;
}
}
public void EasyCreate(int boltno1st, int boltcnt, int poslen)
{
Bolts.Clear();
int b = 0;
for (int i = 0; i < boltcnt; i++)
{
Bolts.Add(new Range() { Begin = b, End = b + poslen / boltcnt - 1 });
b = Bolts.Last().End + 1;
}
FirstBoltNo = boltno1st;
BorderType = BORDER_TYPE.Null;
BorderBoltNo_B = boltno1st;
BorderBoltNo_E = boltno1st + boltcnt - 1;
//Apply();
}
public void EasyCreate2(int boltno1st, int boltwidth, int poslen)
{
Bolts.Clear();
int b = 0;
int e = b + boltwidth-1;
while (e < poslen)
{
Bolts.Add(new Range() { Begin = b, End = e });
b = e + 1;
e = b + boltwidth - 1;
}
FirstBoltNo = boltno1st;
BorderType = BORDER_TYPE.Null;
BorderBoltNo_B = boltno1st;
BorderBoltNo_E = boltno1st + Bolts.Count - 1;
//Apply();
}
#region INotifyPropertyChanged 成员
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region ISaveToXml 成员
public string[] GetSavePropertyNames()
{
return new string[]{
"FirstBoltNo",
"Bolts",
"BorderType",
"BorderBoltNo_B",
"BorderBoltNo_E",
"BorderBoltNo_M",
"Smooth"
};
}
#endregion
#region ITDParam 成员
public string FileName
{
get;
set;
}
public string DirectoryName
{
get;
set;
}
public string Path
{
get
{
if (string.IsNullOrEmpty(DirectoryName))
return FileName;
else
return DirectoryName + @"\" + FileName;
}
set
{
DirectoryName = System.IO.Path.GetDirectoryName(value);
FileName = System.IO.Path.GetFileName(value);
}
}
public bool Load(string name)
{
if (name != null)
FileName = name;
return Misc.SaveToXmlHepler.Load(Path, this);
}
public bool Save(string name)
{
if (name != null)
FileName = name;
return Misc.SaveToXmlHepler.Save(Path, this);
}
#endregion
#region IBoltMapBase
public void GetBolts(out int boltno1st, out IEnumerable bolts)
{
boltno1st = FirstBoltNo;
bolts = Bolts;
}
public void GetScanRange(Range boltno, out int posBegin, out int posEnd)
{
int boltindex = boltno.Begin - FirstBoltNo;
if (boltindex < 0)
boltindex = 0;
else if (boltindex >= NBolts)
boltindex = NBolts - 1;
posBegin = Bolts[boltindex].Begin;
boltindex = boltno.End - FirstBoltNo;
if (boltindex < 0)
boltindex = 0;
else if (boltindex >= NBolts)
boltindex = NBolts - 1;
posEnd = Bolts[boltindex].End;
}
public int GetBoltIndex_fromPos(int pos)
{
return pos / BoltWidth;
}
#region 用于动态生成分区数据
public void InitBoltAD()
{
dyn.Init();
}
public bool UpdateBoltAD(int[] data, int start_pos, int posOfGrid, Misc.DIRECTION direction, out int start_boltIndex, out int[] boltAD)
{
return dyn.UpdateBoltAD(data, start_pos, posOfGrid, direction, out start_boltIndex, out boltAD);
}
#endregion
#region 根据边界调整分区
public void InitExChange()
{
this.helper.InitExChange();
}
public void CalExChange(Misc.DIRECTION direction, Range bolt_r)
{
CalExChange(direction, bolt_r.Begin, bolt_r.End);
}
public void CalExChange(Misc.DIRECTION direction, int borderPosBegin, int borderPosEnd)
{
int idx = 0;
if (direction == Misc.DIRECTION.BACKWARD)
idx = 1;
FLY.Thick.Base.Server.BoltMapHelper.ExChange exchange = helper.mExChange[idx];
exchange.Init();
int borderPosMid = (borderPosBegin + borderPosEnd) / 2;
int org_borderPosBegin;
int org_borderPosEnd;
int org_borderPosMid;
int borderboltindex_b = BorderBoltNo_B - FirstBoltNo;
int borderboltindex_e = BorderBoltNo_E - FirstBoltNo;
if (borderboltindex_b < 0)
borderboltindex_b = 0;
else if (borderboltindex_b >= NBolts)
borderboltindex_b = 0;
if (borderboltindex_e < borderboltindex_b)
borderboltindex_e = NBolts;
else if (borderboltindex_e >= NBolts)
borderboltindex_e = NBolts;
switch (BorderType)
{
case BORDER_TYPE.Null:
{
} break;
case BORDER_TYPE.BeginEnd:
{
org_borderPosBegin = Bolts[borderboltindex_b].Begin;
org_borderPosEnd = Bolts[borderboltindex_e].End;
exchange.Amp = ((double)(borderPosEnd - borderPosBegin)) / (org_borderPosEnd - org_borderPosBegin);
exchange.Offset = (int)(borderPosBegin - org_borderPosBegin * exchange.Amp);
} break;
case BORDER_TYPE.Begin:
{
org_borderPosBegin = Bolts[borderboltindex_b].Begin;
exchange.Offset = (int)(borderPosBegin - org_borderPosBegin * exchange.Amp);
} break;
case BORDER_TYPE.End:
{
org_borderPosEnd = Bolts[borderboltindex_e].End;
exchange.Offset = (int)(borderPosEnd - org_borderPosEnd * exchange.Amp);
} break;
case BORDER_TYPE.Mid:
{
org_borderPosMid = (Bolts[borderboltindex_b].Begin + Bolts[borderboltindex_e].End) / 2;
exchange.Offset = (int)(borderPosMid - org_borderPosMid * exchange.Amp);
} break;
}
}
public int PositionExchange(Misc.DIRECTION direction, int position)
{
return helper.PositionExchange(direction, position);
}
public int BoltExchange(Misc.DIRECTION direction, int bolt_pos)
{
return helper.BoltExchange(direction, bolt_pos);
}
#endregion
public int[] Map(Misc.DIRECTION direction, int posBegin, int posOfGrid, int[] dat)
{
return helper.Map(direction, posBegin, posOfGrid, dat);
}
#endregion
}
public class DynBoltAD
{
#region 动态扫描时,提前算分区的AD值,正常时 通过 grid数据划分的
private const int NBOLTS_AD = 20;
private int[] boltADIndex = new int[NBOLTS_AD];
private int[] boltADSum = new int[NBOLTS_AD];
private int[] boltADCnt = new int[NBOLTS_AD];
#endregion
IBoltMapBase boltmap;
public DynBoltAD(IBoltMapBase boltmap)
{
this.boltmap = boltmap;
}
public void Init()
{
for (int i = 1; i < NBOLTS_AD; i++)
{
boltADIndex[i] = -1;
boltADSum[i] = boltADCnt[i] = 0;
}
}
private bool UpdateBoltAD(int ad, int position, Misc.DIRECTION direction, out int boltIndex, out int boltAD)
{
boltAD = Misc.MyBase.NULL_VALUE;
boltIndex = -1;
bool ret = false;
int min, max;
int i, j;
int curr_boltno1st;//当前分区表 1st分区号
IEnumerable curr_bolts;//当前分区表
int curr_nbolts;//当前分区总数
boltmap.GetBolts(out curr_boltno1st, out curr_bolts);
curr_nbolts = curr_bolts.Count();
position = boltmap.PositionExchange(direction, position);
switch (direction)
{
case Misc.DIRECTION.FORWARD:
max = int.MinValue;
for (i = 1; i < NBOLTS_AD; i++)
{
int end;
if (boltADIndex[i] < 0) continue;
if (boltADIndex[i] >= curr_nbolts)
{
//这个是有问题的
continue;
}
if (boltADIndex[i] > max)
max = boltADIndex[i];
end = curr_bolts.ElementAt(boltADIndex[i]).End;
if (position > end)
{
int temp = Misc.MyBase.NULL_VALUE;
if (boltADCnt[i] > 0)
temp = boltADSum[i] / boltADCnt[i];
boltAD = temp;
boltIndex = boltADIndex[i];
ret = true;
boltADIndex[i] = -1;
boltADSum[i] = boltADCnt[i] = 0;
}
else
{
if (ad != Misc.MyBase.NULL_VALUE)
{
boltADSum[i] += ad;
boltADCnt[i]++;
}
}
}
if (max == int.MinValue)
{
FindBolt(position);
}
else
{
for (i = 1; max + i < curr_nbolts; i++)
{
if (position > curr_bolts.ElementAt(max + i).Begin)
{
if ((j = GetFreeBoltAD()) < 0)
{
break;
}
else
{
boltADIndex[j] = max + i;
if (ad != Misc.MyBase.NULL_VALUE)
{
boltADCnt[j] = 1;
boltADSum[j] = ad;
}
else
{
boltADCnt[j] = 0;
boltADSum[j] = 0;
}
}
}
else
break;
}
}
break;
case Misc.DIRECTION.BACKWARD:
min = int.MaxValue;
for (i = 1; i < NBOLTS_AD; i++)
{
if (boltADIndex[i] < 0) continue;
if (boltADIndex[i] >= curr_nbolts)
{
//这个是有问题的
continue;
}
if (boltADIndex[i] < min)
min = boltADIndex[i];
if ((position < (curr_bolts.ElementAt(boltADIndex[i]).Begin)) || (position <= 0))
{
int temp = Misc.MyBase.NULL_VALUE;
if (boltADCnt[i] > 0)
{
temp = boltADSum[i] / boltADCnt[i];
}
boltAD = temp;
boltIndex = boltADIndex[i];
ret = true;
boltADIndex[i] = -1;
boltADSum[i] = boltADCnt[i] = 0;
}
else
{
if (ad != Misc.MyBase.NULL_VALUE)
{
boltADSum[i] += ad;
boltADCnt[i]++;
}
}
}
if (min == int.MaxValue)
FindBolt(position);
else
{
for (i = 1; min - i >= 0; i++)
{
if (position < curr_bolts.ElementAt(min - i).End)
{
if ((j = GetFreeBoltAD()) < 0)
break;
else
{
boltADIndex[j] = min - i;
if (ad != Misc.MyBase.NULL_VALUE)
{
boltADCnt[j] = 1;
boltADSum[j] = ad;
}
else
{
boltADCnt[j] = 0;
boltADSum[j] = 0;
}
}
}
else
break;
}
}
break;
}
return ret;
}
private void FindBolt(int position)
{
int curr_boltno1st;//当前分区表 1st分区号
IEnumerable curr_bolts;//当前分区表
int curr_nbolts;
boltmap.GetBolts(out curr_boltno1st, out curr_bolts);
curr_nbolts = curr_bolts.Count();
int i, j = 1;
for (i = 0; i < curr_nbolts; i++)
{
if (position > (curr_bolts.ElementAt(i).End))
continue;
if ((position < (curr_bolts.ElementAt(i).Begin)) || (position <= 0))
break;
boltADIndex[j] = i;
boltADSum[j] = boltADCnt[j] = 0;
j++;
if (j >= NBOLTS_AD) break;
}
}
private int GetFreeBoltAD()
{
for (int i = 1; i < NBOLTS_AD; i++)
if (boltADIndex[i] < 0)
return i;
return -1;
}
public bool UpdateBoltAD(int[] data, int start_pos, int posOfGrid, Misc.DIRECTION direction, out int start_boltIndex, out int[] boltAD)
{
int nbolts = boltmap.NBolts;
int start_grid = start_pos / posOfGrid;
start_boltIndex = -1;
List boltdata = new List();
for (int i = 0; i < data.Length; i++)
{
int boltIndex;
int boltad;
bool ret = UpdateBoltAD(data[i], (start_grid + i) * posOfGrid, direction, out boltIndex, out boltad);
if (ret == true)
{
if (start_boltIndex == -1)
start_boltIndex = boltIndex;
boltdata.Add(boltad);
}
}
if (boltdata.Count() == 0)
{
boltAD = null;
return false;
}
start_boltIndex = GetInfoBoltIndex(start_boltIndex);
while (start_boltIndex < 0 && boltdata.Count()>0)
{
boltdata.RemoveAt(0);
start_boltIndex--;
}
while ((start_boltIndex + boltdata.Count() > nbolts) && boltdata.Count() > 0)
{
boltdata.RemoveAt(boltdata.Count() - 1);
}
boltAD = boltdata.ToArray();
if (boltAD.Count() > 0)
return true;
return false;
}
///
/// 转换总分区表 的序号
///
/// 当前分区表的序号
///
int GetInfoBoltIndex(int curr_boltindex)
{
int curr_boltno1st;
IEnumerable curr_bolts;
boltmap.GetBolts(out curr_boltno1st, out curr_bolts);
int offset = curr_boltno1st - boltmap.FirstBoltNo;
return curr_boltindex + offset;
}
}
public class BoltMapHelper
{
IBoltMapBase boltmap;
public BoltMapHelper(IBoltMapBase boltmap)
{
this.boltmap = boltmap;
}
public int[] Map(Misc.DIRECTION direction, int posBegin, int posOfGrid, int[] dat)
{
int boltno1st = boltmap.FirstBoltNo;
int nbolts = boltmap.NBolts;
int curr_boltno1st;//当前分区表 1st分区号
IEnumerable curr_bolts;//当前分区表
int curr_nbolts;
boltmap.GetBolts(out curr_boltno1st, out curr_bolts);
curr_nbolts = curr_bolts.Count();
int[] frame = new int[curr_nbolts];
int gridbegin = posBegin / posOfGrid;
int len = dat.Length;
for (int i = 0; i < curr_nbolts; i++)
{
int sum = 0;
int cnt = 0;
int total = 0;
int j;
int begin = curr_bolts.ElementAt(i).Begin;
int end = curr_bolts.ElementAt(i).End;
begin = boltmap.BoltExchange(direction, begin);
end = boltmap.BoltExchange(direction, end);
int begin_grid = begin / posOfGrid;
int end_grid = end / posOfGrid;
for (j = begin_grid; j <= end_grid; j++)
{
int index = j - gridbegin;
if ((index >= 0) && (index < len))
{
if (Misc.MyBase.ISVALIDATA(dat[index]))
{
sum += dat[index];
cnt++;
}
total++;
}
}
//数据有效必须是 有效数据 多于 一个分区总数的 1/3
if (cnt > (total / 3))
{
frame[i] = sum / cnt;
}
else
{
frame[i] = Misc.MyBase.NULL_VALUE;
}
}
//数据平滑
int smooth = boltmap.Smooth;
if (smooth < 0)
smooth = 0;
else if (smooth > 10)
smooth = 10;
int[] frame2;
if (smooth > 0)
{
frame2 = new int[curr_nbolts];
for (int i = 0; i < curr_nbolts; i++)
{
int sum = 0;
int cnt = 0;
int index_b = i - smooth;
int index_e = i + smooth;
for (int j = index_b; j <= index_e; j++)
{
if ((j >= 0) && (j < curr_nbolts))
{
if (Misc.MyBase.ISVALIDATA(frame[j]))
{
sum += frame[j];
cnt++;
}
}
}
if (cnt > 0)
{
frame2[i] = sum / cnt;
}
else
{
frame2[i] = Misc.MyBase.NULL_VALUE;
}
}
}
else
{
frame2 = frame;
}
frame = new int[nbolts];
int offset = curr_boltno1st - boltno1st;
for (int i = 0; i < nbolts; i++)
{
if (i < offset)
{
frame[i] = Misc.MyBase.NULL_VALUE;
}
else if (i < offset + curr_nbolts)
{
frame[i] = frame2[i - offset];
}
else
{
frame[i] = Misc.MyBase.NULL_VALUE;
}
}
return frame;
}
#region 根据边界调整分区
public class ExChange
{
///
/// 平移
///
public int Offset { get; set; }
///
/// 比例
///
public double Amp { get; set; } = 1;
///
/// 初始化
///
public void Init()
{
Offset = 0;
Amp = 1;
}
}
public ExChange[] mExChange = new ExChange[2] { new ExChange(), new ExChange() };
public void InitExChange()
{
for (int i = 0; i < 2; i++)
{
ExChange exchange = mExChange[i];
exchange.Init();
}
}
public int PositionExchange(Misc.DIRECTION direction, int position)
{
int idx = 0;
if (direction == Misc.DIRECTION.BACKWARD)
idx = 1;
ExChange exchange = mExChange[idx];
return (int)((position - exchange.Offset) / exchange.Amp);
}
public int BoltExchange(Misc.DIRECTION direction, int bolt_pos)
{
int idx = 0;
if (direction == Misc.DIRECTION.BACKWARD)
idx = 1;
ExChange exchange = mExChange[idx];
return (int)(bolt_pos * exchange.Amp) + exchange.Offset;
}
#endregion
}
}