123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785 |
-
- using Unity.Mathematics;
- using System.Drawing;
- using System.Text;
- using BHJD.DEMdll.Public;
- using Newtonsoft.Json;
- namespace QuYuSaoMiao
- {
- public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
- {
- /// <summary>Whether the current thread is processing work items.</summary>
- [ThreadStatic]
- private static bool _currentThreadIsProcessingItems;
- /// <summary>The list of tasks to be executed.</summary>
- private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
- /// <summary>The maximum concurrency level allowed by this scheduler.</summary>
- private readonly int _maxDegreeOfParallelism;
- /// <summary>Whether the scheduler is currently processing work items.</summary>
- private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks)
- /// <summary>
- /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
- /// specified degree of parallelism.
- /// </summary>
- /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
- public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
- {
- if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
- _maxDegreeOfParallelism = maxDegreeOfParallelism;
- }
- /// <summary>
- /// current executing number;
- /// </summary>
- public int CurrentCount { get; set; }
- /// <summary>Queues a task to the scheduler.</summary>
- /// <param name="task">The task to be queued.</param>
- protected sealed override void QueueTask(Task task)
- {
- // Add the task to the list of tasks to be processed. If there aren't enough
- // delegates currently queued or running to process tasks, schedule another.
- lock (_tasks)
- {
- //Console.WriteLine("Task Count : {0} ", _tasks.Count);
- _tasks.AddLast(task);
- if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
- {
- ++_delegatesQueuedOrRunning;
- NotifyThreadPoolOfPendingWork();
- }
- }
- }
- int executingCount = 0;
- private static object executeLock = new object();
- /// <summary>
- /// Informs the ThreadPool that there's work to be executed for this scheduler.
- /// </summary>
- private void NotifyThreadPoolOfPendingWork()
- {
- ThreadPool.UnsafeQueueUserWorkItem(_ =>
- {
- // Note that the current thread is now processing work items.
- // This is necessary to enable inlining of tasks into this thread.
- _currentThreadIsProcessingItems = true;
- try
- {
- // Process all available items in the queue.
- while (true)
- {
- Task item;
- lock (_tasks)
- {
- // When there are no more items to be processed,
- // note that we're done processing, and get out.
- if (_tasks.Count == 0)
- {
- --_delegatesQueuedOrRunning;
- break;
- }
- // Get the next item from the queue
- item = _tasks.First.Value;
- _tasks.RemoveFirst();
- }
- // Execute the task we pulled out of the queue
- base.TryExecuteTask(item);
- }
- }
- // We're done processing items on the current thread
- finally { _currentThreadIsProcessingItems = false; }
- }, null);
- }
- /// <summary>Attempts to execute the specified task on the current thread.</summary>
- /// <param name="task">The task to be executed.</param>
- /// <param name="taskWasPreviouslyQueued"></param>
- /// <returns>Whether the task could be executed on the current thread.</returns>
- protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
- {
- // If this thread isn't already processing a task, we don't support inlining
- if (!_currentThreadIsProcessingItems) return false;
- // If the task was previously queued, remove it from the queue
- if (taskWasPreviouslyQueued) TryDequeue(task);
- // Try to run the task.
- return base.TryExecuteTask(task);
- }
- /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
- /// <param name="task">The task to be removed.</param>
- /// <returns>Whether the task could be found and removed.</returns>
- protected sealed override bool TryDequeue(Task task)
- {
- lock (_tasks) return _tasks.Remove(task);
- }
- /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
- public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
- /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
- /// <returns>An enumerable of the tasks currently scheduled.</returns>
- protected sealed override IEnumerable<Task> GetScheduledTasks()
- {
- bool lockTaken = false;
- try
- {
- Monitor.TryEnter(_tasks, ref lockTaken);
- if (lockTaken) return _tasks.ToArray();
- else throw new NotSupportedException();
- }
- finally
- {
- if (lockTaken) Monitor.Exit(_tasks);
- }
- }
- }
- public class Height
- {
- public string msg { get; set; }
- public int code { get; set; }
- public double data { get; set; }
- }
- public class TXResult
- {
- public double FirstOneReadyTime { get; set; }
- public double FirstOneArriveTime { get; set; }
- public double FirstOneMaxCover { get; set; }
- public int SingleMaxConnect { get; set; }//仅最大一架,单架输出另立列表
- public double AverageTotalCover { get; set; }
- public double FullCoverTime { get; set; }
- public int MaxTotalConnect { get; set; }
- public double ConnectTimeRatio { get; set; }
- public double UnitFulfilledRatio { get; set; }
- public string Stability { get; set; }
- public string Robustness { get; set; }
- public string Security { get; set; }
- }
- public class YJTX
- {
- //public static DemHelper DemHelper()//00
- // {
- // IDbHelper db = Factory.Load("10.130.100.5", "5432", "postgres", "postgres", "rescue_patrol_platform");
- // DemHelper ddemHelper = new DemHelper(db);
- // return ddemHelper;
- // }
- public static double[,] MaxMinPoly(List<double[]> poly)//01多边形矩形边界
- {
- List<double> PolyLon = new List<double>();
- List<double> PolyLat = new List<double>();
- foreach (double[] element in poly)
- {
- PolyLon.Add(element[0]);
- PolyLat.Add(element[1]);
- }
- double[,] MM1 = new double[2, 2];
- MM1[0, 0] = PolyLon.Min();//经度最小(西界)
- MM1[0, 1] = PolyLon.Max();//经度最大(东界)
- MM1[1, 0] = PolyLat.Min();//纬度最小(南界)
- MM1[1, 1] = PolyLat.Max();//纬度最大(北界)
- return MM1;
- }
- public static bool isinpoly(double[] zuobiao, List<double[]> poly, DemHelper demHelper)//02已经替换成在边界内算法
- {
- double[,] polyOut = MaxMinPoly(poly);
- if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
- { return false; }
- else
- {
- string polystring = "MULTIPOLYGON(((";
- foreach (double[] element in poly)
- {
- double e0 = element[0];
- double e1 = element[1];
- polystring = polystring + element[0] + " " + element[1] + ",";
- }
- polystring = polystring + poly[0][0] + " " + poly[0][1] + ")))";
- string pointstring = "POINT (" + zuobiao[0] + " " + zuobiao[1] + ")";
- // Console.WriteLine("isinpoly?");
- //Console.WriteLine(pointstring+polystring);
- string r1 = demHelper.doDetermine(pointstring, polystring);
- // Console.WriteLine(r1);
- //double[,] polyOut = MaxMinPoly(poly);
- //if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
- // { return false; }
- // else
- //{
- return (r1 == "True" ? true : false);
- // }
- }
- }
- //03格点生成方法[已删除]:输入前四个为经纬度上下限,数组为多边形,后两个是经纬度分辨率。输出0经,1纬,2高,3是否被侦察的【01】变量。
- //04格点初始化[已删除]
- //05格点显示【已删除】,可以不用
-
- //06两点间距计算,输出米
- public static double distance(double[] P1, double[] P2, DemHelper demHelper)
- {
- //double DL = 6371.004 * Math.Acos(Math.Sin(Math.PI / 180 * P1[1]) * Math.Sin(Math.PI / 180 * P2[1]) + Math.Cos(Math.PI / 180 * P1[1]) * Math.Cos(Math.PI / 180 * P2[1]) * Math.Cos(Math.PI / 180 * (P1[0] - P2[0]))) * 1000;
- //double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
- //return D;
- double3 p1 = new double3();
- double3 p2 = new double3();
- p1.x = P1[0];
- p1.y = P1[1];
- p1.z = P1[2];
- p2.x = P2[0];
- p2.y = P2[1];
- p2.z = P2[2];
- double D1 = demHelper.getDistance(p1, p2);
- //double DD1 = D1;
- //Console.WriteLine("距离:" + D1);
- return D1;
- }
- //07两点间距计算,(本地版),输出米
- public static double distance1(double[] P1, double[] P2)
- {
- double DL = 6371.004 * Math.Acos(Math.Sin(Math.PI / 180 * P1[1]) * Math.Sin(Math.PI / 180 * P2[1]) + Math.Cos(Math.PI / 180 * P1[1]) * Math.Cos(Math.PI / 180 * P2[1]) * Math.Cos(Math.PI / 180 * (P1[0] - P2[0]))) * 1000;
- double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
- return D;
- }
- //08两点间高度角计算,从P1到P2,角度制
- public static double angleH(double[] P1, double[] P2)
- {
- if (P1[2] == P2[2])
- { return 0; }
- else if (P1[0] == P2[0] && P1[1] == P2[1])
- {
- if (P1[2] < P2[2])
- { return 90; }
- else { return -90; }
- }
- else
- {
- //if (P1[2] < P2[2])
- //{
- double angleH = Math.Asin((P2[2] - P1[2]) / distance1(P1, P2)) * (180 / Math.PI);
- return angleH;
- //}
- //else
- //{
- // double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2)) * (180 / Math.PI);
- // return angleH;
- //}
- }
- }
- //09MoveTo,输入单位坐标、目标坐标,输出时步结束时的单位坐标【暂不用】
- public static double[] MoveTo(double[] aircraft, double[] target, double V, double TimeStep, DemHelper demHelper)
- {
- double[] direction = { (target[0] - aircraft[0]) / distance(aircraft, target, demHelper), (target[1] - aircraft[1]) / distance(aircraft, target, demHelper), (target[2] - aircraft[2]) / distance(aircraft, target, demHelper) };
- double[] delta = { direction[0] * V * TimeStep, direction[1] * V * TimeStep, direction[2] * V * TimeStep };
- double[] next = { aircraft[0] + delta[0], aircraft[1] + delta[1], aircraft[2] + delta[2] };
- return next;
- }
- public static bool isBlocked(double[] P1, double[] P2, DemHelper demHelper)//10是否被地形遮挡
- {
- double3 p1 = new double3();
- double3 p2 = new double3();
- p1.x = P1[0];
- p1.y = P1[1];
- p1.z = P1[2];
- p2.x = P2[0];
- p2.y = P2[1];
- p2.z = P2[2];
- string r2 = demHelper.doIntervisibility(p1, p2);//这三行代码用于运行判定
- // Console.WriteLine("r2="+r2);
- return (r2 == "true" ? false : true);
- //return false;
- }
- //11是否符合观察条件【已删除】
-
- //12航线转object【暂不用】
- public static List<object[]> RouteInput(string TurningPointName, List<double[]> TurningPointLocation, string TurningPointType, double TurningPointVelocity, double SegmentFlightFuelConsumption, double SegmentFlightTime, double TurningRadius)
- {
- List<object[]> SCIP = new List<object[]>();
- int i = 0;
- foreach (double[] element in TurningPointLocation)
- {
- object[] SCIPtemt = { $"{TurningPointName}{i}", element, $"{TurningPointType}", TurningPointVelocity, SegmentFlightFuelConsumption, SegmentFlightTime, TurningRadius };
- SCIP.Add(SCIPtemt);
- i++;
- }
- return SCIP;
- }
- //13航线显示,不用管【暂不用】
- public static void ListscanRoute(List<double[]> SCtoRead)
- {
- Console.WriteLine("【showSC】");
- foreach (double[] element in SCtoRead)
- {
- string lontax = element[0].ToString("F5");
- string lattax = element[1].ToString("F5");
- Console.WriteLine("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
- }
- }
- public static double HeightLL(double lon, double lat)//14经纬度提取高程
- {
- string req = "http://10.130.100.5:7785//rescue-platform-service/api/v1/dem/getInfos?lon=";
- req += lon;
- req += "&lat=";
- req += lat;
- var client = new HttpClient();
- //var request = new HttpRequestMessage(HttpMethod.Get, "http://10.130.100.5:7785//rescue-platform-service/api/v1/dem/getInfos?lon=115.32&lat=38.26");
- var request = new HttpRequestMessage(HttpMethod.Get, req);
- var response = client.Send(request);
- response.EnsureSuccessStatusCode();
- string BBB = "";
- if (response.IsSuccessStatusCode)
- {
- string content = response.Content.ReadAsStringAsync().Result; // 同步阻塞调用
- BBB = content;
- //Console.WriteLine(content);
- }
- Height data = JsonConvert.DeserializeObject<Height>(BBB);
- //Console.WriteLine("AAA");
- //string BBB =await response.Content.ReadAsStringAsync();
- Console.WriteLine("lo" + lon + "la" + lat + "h" + data.data);
- return data.data;
- }
- //15.字符串提取数字段
- public static List<int> intList(string intString)//示例:"1,3-5"
- {
- intString += ",";
- List<int> intList = new List<int>();
- int Length = intString.Length;
- string reading = "";
- string ii = "";
- int head = new int();
- int tail = new int();
- bool isSingle = new bool();
- for (int i = 0; i < Length; i++)
- {
- reading += intString[i];
- ii += intString[i];
- if (int.TryParse(reading, out int result) == true)
- { }
- else if (ii == "," && isSingle == true)
- {
- string readingNum = reading.Remove(reading.Length - 1);
- int adding = int.Parse(readingNum);
- intList.Add(adding);
- reading = "";
- }
- else if (ii == "-")
- {
- string readingNum = reading.Remove(reading.Length - 1);
- head = int.Parse(readingNum);
- isSingle = false;
- reading = "";
- }
- else if (ii == "," && isSingle == false)
- {
- string readingNum = reading.Remove(reading.Length - 1);
- tail = int.Parse(readingNum);
- for (int j = head; j <= tail; j++)
- { intList.Add(j); }
- isSingle = true;
- reading = "";
- }
- else
- {
- Console.WriteLine("int列表转换的字符串有非法字符,仅支持整数、“,”、“-”,无空格");
- }
- ii = "";
- }
- //foreach(int i in intList) { Console.WriteLine("int:"+i); }
- return intList;
- }
- //16.环形航线坐标更新
- public static double[] CirculeCoo(double Time, List<double[]> Route3D, double Speed)
- {
- double TotalTime = 0;
- List<double> TimeP = new List<double>();
- TimeP.Add(TotalTime);
- for (int i = 1; i < Route3D.Count; i++)
- {
- TotalTime += (distance1(Route3D[i], Route3D[i - 1]) / Speed);
- TimeP.Add(TotalTime);
- }
- TotalTime += (distance1(Route3D[0], Route3D[Route3D.Count - 1]) / Speed);
- TimeP.Add(TotalTime);
- double RestTime = Time % TotalTime;
- //Console.WriteLine(TotalTime+"TT||RT"+RestTime);
- double[] Head = new double[3];
- double[] Tail = new double[3];
- double[] Coo = new double[3];
- Route3D.Add(Route3D[0]);
- double ratioRoute = new double();
- for (int i = 0; i < TimeP.Count - 1; i++)//TimeP.Count比点数大1
- {
- if (RestTime >= TimeP[i] && RestTime <= TimeP[i + 1])
- {
- Head = Route3D[i];
- Tail = Route3D[i + 1];
- ratioRoute = (RestTime - TimeP[i]) / (TimeP[i + 1] - TimeP[i]);
- break;
- }
- }
- Coo[0] = Head[0] * (1 - ratioRoute) + Tail[0] * ratioRoute;
- Coo[1] = Head[1] * (1 - ratioRoute) + Tail[1] * ratioRoute;
- Coo[2] = Head[2] * (1 - ratioRoute) + Tail[2] * ratioRoute;
- double[] Coo1 = Coo;
- //Console.WriteLine("EEEEEEEEE" + Coo1[0] + "NNNNNNNNNN" + Coo1[1] + "HHHHHHHH" + Coo1[2]);
- Route3D.RemoveAt(Route3D.Count - 1);
- return Coo;
- }
- //17.坐标更新
- public static void statusMove(List<object[]> status, double Time, List<double[]> Route3D, double Speed, int movingUnit)//速度单位是米每秒
- {
- object[] statusMove = status[movingUnit];
- double[] CooTemp = (double[])statusMove[1];
- double[] CooNow = CirculeCoo(Time, Route3D, Speed);
- statusMove[1] = CooNow;//************需要更新为读取经纬高!!!
- //double Direction0 = Direction(CooTemp, CooNow);
- //statusMove[6] = Direction0;//
- double SailDirection =(Math.PI/2- Direction(CooTemp, CooNow)+ 2 * Math.PI) %(2* Math.PI);//*************需要更新为读取航向!!!!SailDirection是系统定义的航向
- double direction0 = (Math.PI / 2 - SailDirection + 2 * Math.PI) % (2 * Math.PI);
- if(direction0> Math.PI) { direction0 -= 2 * Math.PI; }
- statusMove[6] = direction0*180/Math.PI;//将正北顺时针0-360航向角转化为正东逆时针+-180航向角.记录这个。
- Console.WriteLine("航向角:"+ statusMove[6]);
- bool isMoved = true;
- statusMove[10] = isMoved;
- //status.RemoveAt(movingUnit);
- //status.Insert(movingUnit, statusMove);
- status[movingUnit] = statusMove;
- //return statusMove;
- }
-
- //通信设备定义,后期作为输入项
- //0.int编号
- //1.srting名称
- //2.通信中心频率,MHz
- //3.发射功率,dBm
- //4.发射天线增益,dB
- //5.接收机灵敏度,dBm
- //6.接收天线增益.dB
- //7.bool是否有转发功能
- //8.double发送流量限制Mbps
- //9.bool是否能接入外界网络
- //10.double[]通信角度{angleH0,angleH1,angleD0,angleD1}
- public static List<object[]> DeviceRead( List<object[]> DeviceDTBS)
- {
- List<object[]> Device = new List<object[]>();
- int i = 0;
-
- foreach(object[] element in DeviceDTBS)
- {
-
- int Number = i;
- string DeviceName = (string)element[0];
- double F = (double)element[1];
- double Pt = (double)element[2];
- double Gt = (double)element[3];
- double Pr = (double)element[4];
- double Gr = (double)element[5];
- bool canRelay = (bool)element[6];
- double RelayLimit = (double)element[7];
- bool isConnected = (bool)element[8];
- double[] AngleLimit = { (double)element[9], (double)element[10], (double)element[11], (double)element[12] };
- object[] DeviceToAdd = { Number, DeviceName, F, Pt, Gt, Pr, Gr, canRelay, RelayLimit, isConnected, AngleLimit };
- Device.Add(DeviceToAdd);
- i++;
-
- }
-
- return Device;
- }
- //通信单位定义,后期作为输入项
- //0.编号
- //1.名称
- //2.通信载荷种类int
- //3.double[]经纬高[初始位置]
- //4.本地遮挡衰减dB
- //5.本地数据流量需求Mbps
- //6.bool是否高优先级用户
- //7.bool是否通信基点
- //8.double初始朝向
- //9.bool是否网格
- public static void AddUnit(List<object[]> Unit, string Name, string DeviceName, double[] Location,double LossLocal,
- double RequiredData, bool isVIP,
- bool isBase, double direction0, List<object[]> Device)
- {
- int DeviceNumber = new int();
- for (int i = 0; i < Device.Count; i++)
- {
- if ((string)Device[i][1] == DeviceName)
- { DeviceNumber = i; break; }
- }
- int Number = Unit.Count;
- double H;
-
- double[] LocationH = { Location[0], Location[1], Location[2] };
- object[] UnitToAdd = { Number, Name, DeviceNumber, LocationH, LossLocal, RequiredData, isVIP, isBase, direction0, false };
- Unit.Add(UnitToAdd);
- }
- //方向角算法,从P1指向P2,弧度制,正东为0,逆时针,正负Pi
- public static double Direction(double[] P1, double[] P2)
- {
- double EW = 6371.004 * 2 * math.PI * math.cos(math.PI * P1[1] / 180) * (P2[0] - P1[0]) / 360;
- double SN = 6371.004 * 2 * math.PI * (P2[1] - P1[1]) / 360;
- double Direction = Math.Atan2(SN, EW);
- return Direction;
- }
- //通信载荷状态定义
- //0.编号
- //1.double[]经纬高
- //2.bool是否被联通
- //3.int当前通信层级
- //4.bool是否开启【默认开】
- //5.所连基点ID
- //6.double朝向
- //7.double上行数据量
- //8.int上级ID
- //9.List<int>连通性,0无判定,1连通,-1不通,三角。
- //10.是否被移动
- public static List<object[]> status(List<object[]> Unit)
- {
- List<object[]> status = new List<object[]>();
- foreach (object[] element in Unit)
- {
- int num = (int)element[0];
- double[] location = (double[])element[3];
- bool isConnected;
- int level;
- bool isOpen = true;
- double direction = (double)element[8];
- int BaseID;
- double UploadSpeed = 0;
- int upID;
- if ((bool)element[7] == true)
- {
- isConnected = true;
- level = 0;
- BaseID = num;
- upID = num;
- }
- else
- {
- isConnected = false;
- level = -1;
- BaseID = -1;
- upID = -1;
- }
- List<int> canSee = new List<int>();
- for (int i = 0; i < Unit.Count; i++)
- {
- canSee.Add(0);
- }
- bool isMoved = false;
- object[] StatusToAdd = { num, location, isConnected, level, isOpen, BaseID, direction, UploadSpeed, upID, canSee, isMoved };
- status.Add(StatusToAdd);
- }
- return status;
- }
- public static TXResult TXR(double FRT,string Stablility,string Robustness,string Security)
- {
- TXResult TXR = new TXResult();
- TXR.FirstOneReadyTime = FRT;
- TXR.FirstOneArriveTime = -1;
- TXR.FirstOneMaxCover = -1;
- TXR.SingleMaxConnect = -1;
- TXR.AverageTotalCover = -1;
- TXR.FullCoverTime = -1;
- TXR.MaxTotalConnect = -1;
- TXR.ConnectTimeRatio = -1;
- TXR.UnitFulfilledRatio = -1;
- TXR.Stability = Stablility;
- TXR.Robustness = Robustness;
- TXR.Security = Security;
- return TXR;
- }
- //通信余量计算算法
- //AL为航向角
- public static double Margin(int Unit1, int Unit2, List<object[]> Device, List<object[]> Unit, List<object[]> status, double MarginLimit, string TXEnvironment, DemHelper demHelper)
- //MarginLimit为通信余量下限,默认0
- {
- //Console.WriteLine("正在判断" + (string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "的连通性");
- int Device1 = (int)Unit[Unit1][2];//设备属性
- int Device2 = (int)Unit[Unit2][2];
- double F1 = (double)Device[Device1][2];//频率
- double F2 = (double)Device[Device2][2];
- if (F1 - F2 > 1)
- {
- // Console.WriteLine( (string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "不连通:频率不对");
- return -1; }//不对频就结束
- else
- {
- double Pt1 = (double)Device[Device1][3];//发射功率
- double Gt1 = (double)Device[Device1][4];//发射增益
- double Pr1 = (double)Device[Device1][5];//接收功率
- double Gr1 = (double)Device[Device1][6];//接收增益
- double[] AngleLimit1 = (double[])Device[Device1][10];//角度限制
- double LossLocal1 = (double)Unit[Unit1][4];//本地损失
- double[] Location1 = (double[])status[Unit1][1];//位置
- //Console.WriteLine((string)Unit[Unit1][1] + "<--11-->" + (string)Unit[Unit2][1]);
- List<int> canSee1 = (List<int>)status[Unit1][9];
- List<int> canSee2 = (List<int>)status[Unit2][9];
- bool isMoved2 = (bool)status[Unit2][10];
- bool isMoved1 = (bool)status[Unit1][10];
- double Pt2 = (double)Device[Device2][3];
- double Gt2 = (double)Device[Device2][4];
- double Pr2 = (double)Device[Device2][5];
- double Gr2 = (double)Device[Device2][6];
- double[] AngleLimit2 = (double[])Device[Device2][10];
- double LossLocal2 = (double)Unit[Unit2][4];
- double[] Location2 = (double[])status[Unit2][1];
- double D = distance1(Location1, Location2) / 1000;//距离,千米
- double PL12 = 20 * Math.Log10(F1) + 20 * Math.Log10(D) + 32.44;//自由空间
- //Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "的自由空间损耗"+PL12);
- if (TXEnvironment=="郊区"||
- TXEnvironment == "城市" ||
- TXEnvironment == "密集城市" ||
- TXEnvironment == "高层建筑城市" )
- {
- string envi = TXEnvironment;
- double r = distance1(new double[] { Location1[0], Location1[1], 0 }, new double[] { Location2[0], Location2[1], 0 });//水平距离,m
- double f = F1 * 1000000;//频率,Hz
- double h = Math.Abs(Location1[2] - Location2[2]);//高度差,m
- double a = 0, b = 0, n_los = 0, n_nlos = 0;
- switch (envi)
- {
- case "郊区":
- a = 4.88;
- b = 0.43;
- n_los = 0.1;
- n_nlos = 21;
- break;
- case "城市":
- a = 9.61;
- b = 0.16;
- n_los = 1;
- n_nlos = 20;
- break;
- case "密集城市":
- a = 12.08;
- b = 0.11;
- n_los = 1.6;
- n_nlos = 23;
- break;
- case "高层建筑城市":
- a = 27.23;
- b = 0.08;
- n_los = 2.3;
- n_nlos = 34;
- break;
- }
- //double pi = 3.1415926;
- double c = 299552816;
- double A = n_los - n_nlos;
- double B = 20 * Math.Log10(f) + 20 * Math.Log10(4 * Math.PI / c) + n_nlos;
- double fm = 1 + a * Math.Exp(-b * (Math.Atan(h / r)*180/Math.PI - a));
- double pl = A / fm + 10 * Math.Log10(h * h + r * r) + B;
- // double pl = A / fm + 20 * Math.Log10(D*1000)+ B;
- // Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "的自由空间损耗" + PL12+"环境损耗" + pl + " r=" + r + " h=" + h);//+ " A/fm=" + (A / fm));
- PL12 = pl;
- //+ " A/fm=" + (A/fm) + " B+30-20 * Math.Log10(F1)=" + (B+30- 20 * Math.Log10(F1)));
- }
- double Loss12 = PL12
- + LossLocal1
- + LossLocal2;//***损耗计算,暂时仅自由空间+本地损失***
- double SafeL1to2 = Pt1 + Gt1 - Pr2 + Gr2 - MarginLimit;//安全损耗
- double SafeL2to1 = Pt2 + Gt2 - Pr1 + Gr1 - MarginLimit;
- double A1 = Direction(Location1, Location2)*180/Math.PI;//连线方向角
- double A2 = Direction(Location2, Location1) * 180 / Math.PI;
- double AL1 = (double)status[Unit1][6];//单位航向角
- double AL2 = (double)status[Unit2][6];
- double AA1 = (A1 - AL1) % 360;
- double AA2 = (A2 - AL2) % 360;//天线与目标夹角
-
- if (AA1 >180) { AA1 = AA1 - 360; }
- if (AA1 <-180) { AA1 = AA1 + 360; }
- if (AA2 > 180) { AA2 = AA2 - 360; }
- if (AA2 < -180) { AA2 = AA2 +360; }
- //Console.WriteLine("AL1="+AL1+ "AL2=" + AL2+"AA1=" + AA1 + "AA2=" + AA2);
- double AV1 = angleH(Location1, Location2);//垂直高度角
- double AV2 = angleH(Location2, Location1);
- bool isInDirection = false;
- if (AA1 >= AngleLimit1[2] && AA1 <= AngleLimit1[3]
- && AA2 >= AngleLimit2[2] && AA2 <= AngleLimit2[3]
- && AV1 >= AngleLimit1[0] && AV1 <= AngleLimit1[1]
- && AV2 >= AngleLimit2[0] && AV2 <= AngleLimit2[1])
- { isInDirection = true; }//判断是否在角度限制内
- //Console.WriteLine(SafeL2to1 - Loss12);
- //Console.WriteLine(SafeL1to2 - Loss12);
- //Console.WriteLine(isInDirection);
- if (SafeL1to2 >= Loss12 && SafeL2to1 >= Loss12 && isInDirection == true)
- //if (SafeL1to2 >= Loss12 && SafeL2to1 >= Loss12 && isInDirection == true)
- {
- bool isBlock = new bool();
- if (isMoved1 == false && isMoved2 == false && Unit2 < Unit1 && canSee1[Unit2] != 0)
- {
- if (canSee1[Unit2] < 0)
- {
- isBlock = true;
- }
- else
- {
- isBlock = false;
- }
- }
- else if (isMoved1 == false && isMoved2 == false && Unit2 > Unit1 && canSee2[Unit1] != 0)
- {
- if (canSee2[Unit1] < 0)
- {
- isBlock = true;
- }
- else
- {
- isBlock = false;
- }
- }
- else
- {
- //Stopwatch stopwatch = Stopwatch.StartNew();
- isBlock = isBlocked(Location1, Location2, demHelper);//是否被遮挡
- //stopwatch.Stop();
- //Console.WriteLine($"{(string)Unit[Unit1][1]}与{(string)Unit[Unit2][1]}地形判断耗时{stopwatch.ElapsedMilliseconds} 毫秒");
- if (isMoved1 == false && isMoved2 == false)
- {
- if (isBlock == true)
- {
- //Console.WriteLine(Unit2 + "---->" + canSee1.Count);
- //canSee1.RemoveAt(Unit2);
- //canSee1.Insert(Unit2, -1);
- canSee1[Unit2] = -1;
- // Console.WriteLine(Unit1 + "---->" + canSee1.Count);
- //canSee2.RemoveAt(Unit1);
- //canSee2.Insert(Unit1, -1);
- canSee2[Unit1] = -1;
- }
- else
- {
- // Console.WriteLine(Unit2 + "---->" + canSee1.Count);
- //canSee1.RemoveAt(Unit2);
- //canSee1.Insert(Unit2, 1);
- canSee1[Unit2] = 1;
- // Console.WriteLine(Unit1 + "---->" + canSee1.Count);
- //canSee2.RemoveAt(Unit1);
- //canSee2.Insert(Unit1, 1);
- canSee2[Unit1] = 1;
- }
- object[] status1 = status[Unit1];
- object[] status2 = status[Unit2];
- status1[9] = canSee1;
- status2[9] = canSee2;
- //status.RemoveAt(Unit1);
- //status.Insert( Unit1,status1);
- status[Unit1] = status1;
- //status.RemoveAt(Unit2);
- //status.Insert( Unit2,status2);
- status[Unit2] = status2;
- }
- }
- //Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "bolck:" + isBlock);
- if (isBlock != true)
- {
- if (SafeL1to2 >= SafeL2to1)
- {
- //Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "连通");
- return SafeL2to1 - Loss12; }//输出双向通信余量的小者
- else {
- // Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "连通");
- return SafeL1to2 - Loss12; }
- }
- else
- {
- //Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "不连通:地形遮挡");
- return -1;//通不上就返-1
- }
- }
- else
- {
- //Console.WriteLine((string)Unit[Unit1][1] + "与" + (string)Unit[Unit2][1] + "不连通:在距离外");
- return -1;//通不上就返-1
- }
- }
- }
-
- public static List<object[]> ASAStatusLevel(List<object[]> Device, List<object[]> Unit, List<object[]> Status, double MarginLimit, int RelayLimit, string TXEnvironment, DemHelper demHelper)
- //RelayLimit是中继次数限制
- {
- bool[] isOpen = new bool[Unit.Count];//本轮通信是否被激活
- bool[] isConnected = new bool[Unit.Count];//是否被联通
- int[] Level = new int[Unit.Count];//记录本轮通信层级
- double[] margin = new double[Unit.Count];//记录余量
- int[] UpID = new int[Unit.Count];//记录上一级ID
- int[] BaseID = new int[Unit.Count];//记录指向的base
- double[] UploadSpeed = new double[Unit.Count];//记录上行数据速度
- for (int i = 0; i < Unit.Count; i++)//初始化
- {
- isOpen[i] = false;
- margin[i] = -1;
- UploadSpeed[i] = 0;
- if ((bool)Unit[i][7] == true)
- {
- isConnected[i] = true;
- BaseID[i] = (int)Unit[i][0];
- Level[i] = 0;
- UpID[i] = i;
- }
- else
- {
- isConnected[i] = false;
- BaseID[i] = -1;
- Level[i] = -1;
- UpID[i] = -1;
- }
- }
- for (int relay = 1; relay <= RelayLimit; relay++)//relay是将要更新的层级
- {
- //单层初始化
- for (int i = 0; i < Unit.Count; i++)
- {
- if (Level[i] == relay - 1 && (bool)Device[(int)Unit[i][2]][7] == true)
- {
- isOpen[i] = true;//仅开启上一级能中继的设备
- //Console.WriteLine(i + "open");
- }
- else { isOpen[i] = false; }
- }
- //找一个指向上一级的目标
- //TaskFactory fac1 = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(128));
- Task[] LevelTasks = new Task[Unit.Count];// Unit.Count];
- for (int i = 0; i < Unit.Count; i++)
- {
- int ii = i;
- LevelTasks[ii] = Task.Run(() =>
- {
- if (ii < Unit.Count && isOpen[ii] == true)
- {
- //Console.WriteLine("UNC" + Unit.Count);
- Task[] UnitTasks = new Task[Unit.Count];
- for (int j = 0; j < Unit.Count; j++)
- {
- int jj = j;
- UnitTasks[jj] = //fac1.StartNew(s =>
- Task.Run(() =>
- {
- //int Levelj = ;
- double mar = -1;
- if (jj < Unit.Count && ii != jj && (Level[jj] == -1 || Level[jj] == relay))
- {
- mar = Margin(ii, jj, Device, Unit, Status, MarginLimit,TXEnvironment ,demHelper);
- // Console.WriteLine("完成,mar:" + mar + "jj:" + jj);
- if (jj < Unit.Count && mar > 0 && (margin[jj] < 0 || mar > margin[jj]))
- {
- margin[jj] = mar;
- UpID[jj] = ii;
- BaseID[jj] = BaseID[ii];
- Level[jj] = relay;
- isConnected[jj] = true;
- //Console.WriteLine("单位" + ii + "与" + "单位" + jj + "连通");
- }
- }
- //Console.WriteLine("完成单位" + ii + "与" + "单位" + jj + "连通判定");
- }
- );//,ii*Unit.Count+jj);
- }
- Task.WaitAll(UnitTasks);
- }
- });
- }
- Task.WaitAll(LevelTasks);
- }
- for (int rerelay = Level.Max(); rerelay >= 0; rerelay--)//倒查并记录数据流量
- {
- for (int i = 0; i < Unit.Count; i++)
- {
- if (Level[i] == rerelay)
- {
- //Console.WriteLine(i + "号设备上行速率需求" + (double)Unit[i][5] + "Mbps");
- UploadSpeed[i] += (double)Unit[i][5];
- if (i != UpID[i])
- {
- UploadSpeed[UpID[i]] += UploadSpeed[i];
- }
- //Console.WriteLine(i + "号设备上行速率" + UploadSpeed[i] + "Mbps");
- }
- }
- }
- List<object[]> newStatus = new List<object[]>();
- for (int i = 0; i < Unit.Count; i++)
- {
- object[] StatusToAdd = { Status[i][0], Status[i][1], isConnected[i], Level[i], Status[i][4], BaseID[i], Status[i][6], UploadSpeed[i], UpID[i], Status[i][9], Status[i][10] };
- newStatus.Add(StatusToAdd);
- }//将2,3,5写入新Status
- return newStatus;
- }
- public static void ASASLevelCalculate(List<object[]> Device, List<object[]> Unit, List<object[]> Status, double MarginLimit, int RelayLimit, string TXEnvironment, DemHelper demHelper)
- //RelayLimit是中继次数限制
- {
- List<object[]> newStatus = YJTX.ASAStatusLevel(Device, Unit, Status, MarginLimit, RelayLimit, TXEnvironment, demHelper);
- Status.Clear();
- for (int i = 0; i < Unit.Count; i++)
- {
- Status.Add(newStatus[i]);
- }//刷新status
- }
- public static void ShowStatus(List<object[]> Device, List<object[]> Unit, List<object[]> Status)
- {
- for (int i = 0; i < Unit.Count; i++)
- {
- double[] Location = (double[])Status[i][1];
- string ConMark;
- if ((bool)Status[i][2] == true)
- { ConMark = "是"; }
- else
- { ConMark = "否"; }
- string OnMark;
- if ((bool)Status[i][4] == true)
- { OnMark = "开启"; }
- else
- { OnMark = "关闭"; }
- Console.WriteLine("编号:" + (int)Status[i][0] + "|单位名称:" + (string)Unit[i][1] + "|设备名称:" + (string)Device[(int)Unit[i][2]][1] +
- "|位置:E" + Location[0] + "°N" + Location[1] + "°H" + Location[2] + "m|方向角:" + (double)Status[i][6] + "°|连通状态:"
- + ConMark + "|当前通信层级:" + (int)Status[i][3] + "|当前载荷状态:" + OnMark +
- "|所连基点ID:" + (int)Status[i][5] + "上行数据速率:" + (double)Status[i][7] + "Mbps");
- Console.WriteLine("___________________________________________");
- }
- }
- //区域网格生成
- public static List<object[]> TXNPGenerate(List<double[]> juxing, double netscalelon, double netscalelat, double DeviceHeight,
- string DeviceName, string NetName, double LocalLost,
- List<object[]> Device,
- DemHelper demHelper)
- //DeviceHeight设备高度,单位m
- //LocalLost网格本地遮挡,单位dB
- {
- Console.WriteLine("格点生成");
- List<object[]> netpoints = new List<object[]>();
- int DeviceNumber = new int();
- for (int i = 0; i < Device.Count; i++)
- {
- if ((string)Device[i][1] == DeviceName)
- { DeviceNumber = i; break; }
- }
- double lonmin = -1000;
- double lonmax = -1000;
- double latmin = -1000;
- double latmax = -1000;
- foreach (double[] element in juxing)
- {
- if (lonmin == -1000 || element[0] < lonmin)
- { lonmin = element[0]; }
- if (lonmax == -1000 || element[0] > lonmax)
- { lonmax = element[0]; }
- if (latmin == -1000 || element[1] < latmin)
- { latmin = element[1]; }
- if (latmax == -1000 || element[1] > latmax)
- { latmax = element[1]; }
- }
- for (double[] netpointprev = new double[3] { lonmin, latmax, 0 }; netpointprev[1] >= latmin; netpointprev[1] = netpointprev[1] - netscalelat)
- {
- int i = 0;
- for (netpointprev[0] = lonmin; netpointprev[0] <= lonmax; netpointprev[0] = netpointprev[0] + netscalelon)
- {
- if (isinpoly(netpointprev, juxing, demHelper) == true)
- {
- double HH = HeightLL(netpointprev[0], netpointprev[1]);//需要替换为该点【netpointprev[0], netpointprev[1]】高程
- double[] netpointtemp = new double[3] { netpointprev[0], netpointprev[1], HH + DeviceHeight };
- //netpointtemp = netpointprev;
- string GridName = NetName + i;
- object[] GridToAdd = { i, GridName, DeviceNumber, netpointtemp, LocalLost, 0.0, false, false, 0.0, true };
- netpoints.Add(GridToAdd);
- i++;
- }
- }
- }
- return netpoints;
- }
- //区域网格计算
- public static int[] AreaConnectCheck(List<object[]> TXNP,
- List<object[]> Device, List<object[]> Unit, List<object[]> Status,
- int[] UnitInvolved,//计算涉及的通信网络,至少含一基站类目标
- double MarginLimit,//有效计算的通信余量
- string TXEnvironment,
- DemHelper demHelper
- )
- {
- int TXNPCount = TXNP.Count;
- int[] AreaCheck = new int[TXNPCount];
- //if (TXNPCount == 0)
- //{
- // Console.WriteLine("无网格");
- // return AreaCheck;
- //}
- //else
- //{
- List<object[]> NPStatus = status(TXNP);
- for (int i = 0; i < UnitInvolved.Length; i++)
- {
- TXNP.Add(Unit[UnitInvolved[i]]);
- }
- for (int i = 0; i < UnitInvolved.Length; i++)
- {
- object[] StatusToAdd = Status[UnitInvolved[i]];
- bool isMoved = true;
- StatusToAdd[10] = isMoved;
- NPStatus.Add(StatusToAdd);
- //Console.WriteLine("involve" + Status[UnitInvolved[i]].Length);
- }
- List<Object[]> NPstatusLevel = ASAStatusLevel(Device, TXNP, NPStatus, MarginLimit, 1, TXEnvironment, demHelper);
- for (int i = 0; i < TXNPCount; i++)
- {
- if ((int)NPstatusLevel[i][3] > 0)
- {
- AreaCheck[i] = (int)NPstatusLevel[i][5];
- }
- else
- {
- AreaCheck[i] = -1;
- }
- }
- for (int i = 0; i < UnitInvolved.Length; i++)
- {
- TXNP.RemoveAt(TXNP.Count - 1);
- }
- return AreaCheck;
- //}
- }
- public static void AreaCheckPostProcess(double Time, List<double[]> poly, int[] BaseList, int[] AreaConnectCheck, List<object[]> TXNP, string CalculateName, double netscalelon, double netscalelat, List<object[]> GridResult)
- //区域网格后处理
- {
- double[,] MM1 = MaxMinPoly(poly);
- double W = MM1[0, 0];//经度最小(西界)
- double E = MM1[0, 1];//经度最大(东界)
- double S = MM1[1, 0]; //纬度最小(南界)
- double N = MM1[1, 1];//纬度最大(北界);
- double kmPerlat = 111.1;
- double kmPerlon = kmPerlat * Math.Cos((Math.PI / 180) * ((N + S) / 2));
- double SPerGrid = (netscalelon * kmPerlon) * (netscalelat * kmPerlat);
- int NPNumber = AreaConnectCheck.Length;
- int ConnectedNP = 0;
- int[] ConnectedSingle = new int[BaseList.Length];
- for (int j = 0; j < BaseList.Length; j++)
- {
- ConnectedSingle[j] = 0;
- }
- for (int i = 0; i < NPNumber; i++)
- {
- if (AreaConnectCheck[i] >= 0)
- {
- ConnectedNP++;
- for (int j = 0; j < BaseList.Length; j++)
- {
- if (BaseList[j] == AreaConnectCheck[i]) { ConnectedSingle[j]++; }
- }
- }
- }
- double[] AreaSingle = new double[ConnectedSingle.Length];//各单机连接区域面积
- for (int j = 0; j < ConnectedSingle.Length; j++)
- {
- AreaSingle[j] = SPerGrid * ConnectedSingle[j];
- }
- double Ratio = (double)ConnectedNP / NPNumber;
- double AreaTotal = SPerGrid * ConnectedNP;
- Console.WriteLine("计算名称:" + CalculateName + "||网格总数:" + NPNumber + "||连接网格数:" + ConnectedNP + "||比例:" + Ratio * 100 + "%");
- //string csvFilePath = CalculateName + "output.csv";//需csv输出则取消注释1/5
- //using (var writer = new StreamWriter(csvFilePath))//需csv输出则取消注释2/5
- //{//需csv输出则取消注释3/5
- // for (int k = 0; k < NPNumber; k++)
- // {
- // double[] item = (double[])TXNP[k][3];
- // if (AreaConnectCheck[k] >= 0)
- // {
- // string Fmt = "{0} , {1}";
- // for (int i = 0; i <= AreaConnectCheck[k]; i++)
- // { Fmt += " ,"; }
- // Fmt += "{1}";
- // writer.WriteLine(String.Format(Fmt, item[0], item[1]));
- // }
- // else
- // { writer.WriteLine(String.Format("{0} ,{1} ", item[0], item[1])); }
- // }
- //}
- object[] StepResult = { Time, BaseList, AreaSingle, Ratio, AreaTotal };
- GridResult.Add(StepResult);
- }
- //区域内随机数生成
- public static List<object[]> TXRandomGenerate(List<double[]> juxing, int pointnumber, //生成的随机格点数量
- double DeviceHeight,//DeviceHeight设备高度,单位m
- string DeviceName, string NetName, double LocalLost,
- double DataSpeedPerPiont,
- int firstNum,//首点ID
- //List<object[]> Device,
- List<object[]>Device,DemHelper demHelper)
- //LocalLost网格本地遮挡,单位dB
- {
- Console.WriteLine("随机点生成");
- List<object[]> netpoints = new List<object[]>();
- double lonmin = -1000;
- double lonmax = -1000;
- double latmin = -1000;
- double latmax = -1000;
- foreach (double[] element in juxing)
- {
- if (lonmin == -1000 || element[0] < lonmin)
- { lonmin = element[0]; }
- if (lonmax == -1000 || element[0] > lonmax)
- { lonmax = element[0]; }
- if (latmin == -1000 || element[1] < latmin)
- { latmin = element[1]; }
- if (latmax == -1000 || element[1] > latmax)
- { latmax = element[1]; }
- }
- //四界
- int DeviceNumber = new int();
- for (int i = 0; i < Device.Count; i++)
- {
- if ((string)Device[i][1] == DeviceName)
- { DeviceNumber = i; break; }
- }
- System.Random lonRam = new System.Random();
- System.Random latRam = new System.Random();
- TaskFactory fac = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(64));
- Task[] PointTasks = new Task[pointnumber];
- for (int i = 0; i < pointnumber;)
- {
- double lon = lonmin + lonRam.NextDouble() * (lonmax - lonmin);
- double lat = latmin + latRam.NextDouble() * (latmax - latmin);
- double[] netpointprev = { lon, lat };
- if (isinpoly(netpointprev, juxing, demHelper) == true)
- {
- int ii = i;
- //PointTasks[ii] = Task.Run(() =>
- //{
- PointTasks[ii] = fac.StartNew(s =>
- {
- if (ii < pointnumber)
- {
- double HH = HeightLL(netpointprev[0], netpointprev[1]);
- double[] netpointtemp = new double[3] { netpointprev[0], netpointprev[1], HH + DeviceHeight };
- string GridName = NetName + ii;
- object[] GridToAdd = { ii + firstNum, GridName, DeviceNumber, netpointtemp, LocalLost, DataSpeedPerPiont, false, false, 0.0, false };
- netpoints.Add(GridToAdd);
- }
- }, ii);
- //});
- i++;
- }
- }
- //Task.WaitAll(fac.);
- //TaskFactory.Continue(fac);
- Task.WaitAll(PointTasks);
- return netpoints;
- }
- public static void TXRandomAdd(List<double[]> juxing, int pointnumber, //生成的随机格点数量
- double DeviceHeight,//DeviceHeight设备高度,单位m
- string DeviceType, string NetName, double LocalLost,
- double DataSpeedPerPiont,
- //int firstNum,//首点ID
- List<object[]> Unit,
- List<object[]>Device,
- DemHelper demHelper)
- {
- List<object[]> TXNP = TXRandomGenerate(juxing, pointnumber, DeviceHeight, DeviceType, NetName, LocalLost, DataSpeedPerPiont, Unit.Count,Device,demHelper);
- foreach (object[] element in TXNP)
- {
- Unit.Add(element);
- }
- }
- public static void ConnectNetPostProcess(double Time, List<object[]> Device, List<object[]> Unit, List<object[]> Status, string CalculateName, string involvedUnit, List<object[]> NetResult)
- //通信网络后处理
- {
- List<int> involvedUnitNum = intList(involvedUnit);
- bool[] isInvolved = new bool[Status.Count];
- List<int> BaseList = new List<int>();
- List<int> ConnectedSingle = new List<int>();
- List<double> BaseFull = new List<double>();
- for (int i = 0; i < Status.Count; i++)
- {
- isInvolved[i] = false;
- }
- int involvedNP = 0;
- int Fulfilled = 0;
- foreach (int i in involvedUnitNum)
- { if (i < Status.Count)
- {
- isInvolved[i] = true; involvedNP++;
- if ((int)Status[i][3] == 0)
- {
- BaseList.Add(i);
- ConnectedSingle.Add(0);
- double UpLimit = (double)Device[(int)Unit[i][2]][8];
- double UpRatio = (double)Status[i][7] / UpLimit;
- BaseFull.Add(UpRatio);
- }
- }
- }
- int NPNumber = Status.Count;
- int ConnectedNP = 0;
- for (int i = 0; i < NPNumber; i++)
- {
- if ((int)Status[i][3] >= 0 && isInvolved[i] == true)
- {
- ConnectedNP++;
- }
- if ((int)Status[i][3] > 0 && isInvolved[i] == true)
- {
- for (int j = 0; j < BaseList.Count; j++)
- {
- if (BaseList[j] == (int)Status[i][5])
- {
- ConnectedSingle[j]++;
- if (BaseFull[j]<1)
- {
- Fulfilled++;
- }
- }
- }
- }
- }
- int TotalConnected = ConnectedNP - BaseList.Count;
- int nonBasePoint = involvedNP - BaseList.Count;
- double Ratio = (double)TotalConnected / nonBasePoint;
- double FulRatio=(double)Fulfilled/ nonBasePoint;
- object[] StepResult = { Time, BaseList, ConnectedSingle, TotalConnected, BaseFull, FulRatio };
- NetResult.Add(StepResult);
- Console.WriteLine("计算名称:" + CalculateName + "||基站数:" + BaseList.Count + "||非基站节点数:" + nonBasePoint + "||连接节点数:" + TotalConnected + "||比例:" + Ratio * 100 + "%");
- //string csvFilePath = CalculateName + "output.csv";
- //using (var writer = new StreamWriter(csvFilePath))
- //{
- // for (int k = 0; k < NPNumber; k++)
- // {
- // if (isInvolved[k] == true)
- // {
- // double[] item = (double[])Status[k][1];
- // int level = (int)Status[k][3];
- // if ((int)Status[k][3] >= 0)
- // {
- // string Fmt = "{0} , {1},{2}";
- // for (int i = 0; i <= (int)Status[k][5]; i++)
- // { Fmt += " ,"; }
- // Fmt += "{2}";
- // writer.WriteLine(String.Format(Fmt, level, item[0], item[1]));
- // }
- // else
- // { writer.WriteLine(String.Format("{0} ,{1},{2} ", level, item[0], item[1])); }
- // }
- // }
- //}
- }
- public static void Draw(List<double[]> poly, List<double[]> point, List<Color> ColorP, List<List<double[]>> points, List<Color> color, int PxPerKm, string name)//可视化,下一步改成自动颜色!
- {
- // 创建一个位图
- double[,] MM1 = MaxMinPoly(poly);
- double W = MM1[0, 0];//经度最小(西界)
- double E = MM1[0, 1];//经度最大(东界)
- double S = MM1[1, 0]; //纬度最小(南界)
- double N = MM1[1, 1];//纬度最大(北界);
- double kmPerlat = 111.1;
- double kmPerlon = kmPerlat * Math.Cos((Math.PI / 180) * ((N + S) / 2));
- //Console.WriteLine(E+"+"+W);
- static int LonToPx(double lon, double W, double kmPerlon, int PxPerKm)
- {
- double LonKm = (lon - W) * kmPerlon;
- int LonPx = (int)(LonKm * PxPerKm);
- return LonPx;
- }
- static int LatToPx(double lat, double N, double kmPerlat, int PxPerKm)//从北向南!!
- {
- double LatKm = (N - lat) * kmPerlat;
- int LatPx = (int)(LatKm * PxPerKm);
- return LatPx;
- }
- int EW = LonToPx(E, W, kmPerlon, PxPerKm);
- int NS = LatToPx(S, N, kmPerlat, PxPerKm);
- //Console.WriteLine(EW + "EW|NS" + NS);
- using Bitmap bitmap = new Bitmap(EW, NS);//位图大小东西南北界
- using (Graphics g = Graphics.FromImage(bitmap))
- {
- g.Clear(Color.White); // 使用Clear方法填充背景色
- }
- using Graphics graphics = Graphics.FromImage(bitmap);
- for (int i = 1; i < poly.Count; i++)
- {
- int penWidth = math.max(EW, NS) / 500;
- using Pen Pen = new Pen(Color.Black, penWidth);
- Point Point1 = new Point(LonToPx(poly[i - 1][0], W, kmPerlon, PxPerKm), LatToPx(poly[i - 1][1], N, kmPerlat, PxPerKm));
- Point Point2 = new Point(LonToPx(poly[i][0], W, kmPerlon, PxPerKm), LatToPx(poly[i][1], N, kmPerlat, PxPerKm));
- graphics.DrawLine(Pen, Point1, Point2);
- }
- for (int i = 0; i < point.Count; i++)
- {
- int penWidth = math.max(EW, NS) / 500;
- using Pen Pen = new Pen(ColorP[i], penWidth);
- //Rectangle rg = new Rectangle(0, 0, math.max(EW, NS) / 300, math.max(EW, NS) / 300);
- float RGsize = math.max(EW, NS) / 300;
- graphics.DrawRectangle(Pen, LonToPx(point[i][0], W, kmPerlon, PxPerKm) - (int)(0.5 * RGsize), LatToPx(point[i][1], N, kmPerlat, PxPerKm) - (int)(0.5 * RGsize), RGsize, RGsize);
- }
- for (int i = 0; i < points.Count; i++)
- {
- int penWidth = math.max(EW, NS) / 1000;
- using Pen Pen = new Pen(color[i % color.Count], penWidth);
- for (int j = 0; j < points[i].Count; j++)
- {
- Point Point1 = new Point(LonToPx(points[i][j][0], W, kmPerlon, PxPerKm), LatToPx(points[i][j][1], N, kmPerlat, PxPerKm));
- Point Point2 = new Point(LonToPx(points[i][j][2], W, kmPerlon, PxPerKm), LatToPx(points[i][j][3], N, kmPerlat, PxPerKm));
- graphics.DrawLine(Pen, Point1, Point2);
- }
- }
- // 定义两个坐标点
- // Point point1 = new Point(50, 50);
- // Point point2 = new Point(150, 150);
- // Point point3= new Point(100, 150);
- // 使用Pen来定义直线的颜色和宽度
- // using Pen pen = new Pen(Color.Black, 2);
- // 画直线
- // graphics.DrawLine(pen, point1, point2);
- // graphics.DrawLine(pen, point1, point3);
- // 保存图像到文件
- //bitmap.Save("line.png");
- // 或者显示图像
- bitmap.Save(name + ".jpeg");
- Console.WriteLine("已画制并保存到" + name + ".jpeg文件中。||" + EW + "EW|NS" + NS);
- }
- public static void Drawnet(List<object[]> Status, string involvedUnit, List<double[]> poly, int PxPerKm, string name)
- {
- List<Color> color = new List<Color>();
- //color.Add(Color.Black);
- color.Add(Color.Red);
- color.Add(Color.Orange);
- color.Add(Color.Yellow);
- color.Add(Color.Green);
- color.Add(Color.Cyan);
- color.Add(Color.Blue);
- color.Add(Color.Purple);
- List<Color> colorP = new List<Color>();//不同基站的上色方案:红橙黄绿青蓝紫,循环
- List<int> involvedUnitNum = intList(involvedUnit);//读取需要画进去的单位ID
- List<List<double[]>> points = new List<List<double[]>>();//把每个基站连接的不同单位存储在不同的List里,方便上色
- List<double[]> UnitsP = new List<double[]>();
- int[] BaseCatalogue = new int[Status.Count];//基站单位着色索引
- int BaseTemp = 0;
- bool[] isInvolved = new bool[Status.Count];
- for (int i = 0; i < Status.Count; i++)//找出基站并针对基站情况初始化列表
- {
- isInvolved[i] = false;//true为画入的单位
- if ((int)Status[i][3] == 0)//是基站
- {
- BaseCatalogue[i] = BaseTemp;//加入基站单位着色索引,表示该单位为目录中第 BaseTemp+1个基站
- BaseTemp++;
- points.Add(new List<double[]>());//为每个基站新建一个列表
- }
- else
- { BaseCatalogue[i] = -1; }
- }
- foreach (int i in involvedUnitNum) { if (i < isInvolved.Length) { isInvolved[i] = true; } }//将需要画入的单位画入开关打开
- foreach (object[] element in Status)
- {
- if (isInvolved[(int)element[0]] == true)//若画入开关打开
- {
- UnitsP.Add((double[])element[1]);//记录该点坐标用于散点绘制
- if ((int)element[3] >= 1)
- {
- int BaseID = (int)element[5];
- int upID = (int)element[8];
- double[] point12 = new double[4];
- point12[0] = ((double[])element[1])[0];
- point12[1] = ((double[])element[1])[1];
- double[] pointUp = (double[])Status[upID][1];
- point12[2] = pointUp[0];
- point12[3] = pointUp[1];
- points[BaseCatalogue[BaseID]].Add(point12);
- colorP.Add(color[BaseCatalogue[BaseID] % color.Count]);
- }
- else if ((int)element[3] == 0)
- {
- colorP.Add(Color.Magenta);
- }
- else
- { colorP.Add(Color.Black); }
- }
- }
- Draw(poly, UnitsP, colorP, points, color, PxPerKm, name);
- }
- public static void Drawgrid(List<double[]> poly, List<object[]> Grids, int[] ACC, int PxPerKm, string name, double netscalelon, double netscalelat)
- {
- List<double[]> UnitsP = new List<double[]>();
- foreach (object[] element in Grids)
- {
- UnitsP.Add((double[])element[3]);
- }
- List<Color> color = new List<Color>();
- //color.Add(Color.Black);
- //color.Add(Color.White);
- color.Add(Color.Red);
- color.Add(Color.Orange);
- color.Add(Color.Yellow);
- color.Add(Color.Green);
- color.Add(Color.Cyan);
- color.Add(Color.Blue);
- color.Add(Color.Purple);
- // 创建一个位图
- double[,] MM1 = MaxMinPoly(poly);
- double W = MM1[0, 0];//经度最小(西界)
- double E = MM1[0, 1];//经度最大(东界)
- double S = MM1[1, 0]; //纬度最小(南界)
- double N = MM1[1, 1];//纬度最大(北界);
- double kmPerlat = 111.1;
- double kmPerlon = kmPerlat * Math.Cos((Math.PI / 180) * ((N + S) / 2));
- //Console.WriteLine(E + "+" + W);
- static int LonToPx(double lon, double W, double kmPerlon, int PxPerKm)
- {
- double LonKm = (lon - W) * kmPerlon;
- int LonPx = (int)(LonKm * PxPerKm);
- return LonPx;
- }
- static int LatToPx(double lat, double N, double kmPerlat, int PxPerKm)//从北向南!!
- {
- double LatKm = (N - lat) * kmPerlat;
- int LatPx = (int)(LatKm * PxPerKm);
- return LatPx;
- }
- int EW = LonToPx(E, W, kmPerlon, PxPerKm);
- int NS = LatToPx(S, N, kmPerlat, PxPerKm);
- int RGEW = LonToPx(W + netscalelon, W, kmPerlon, PxPerKm);
- int RGNS = LatToPx(N - netscalelat, N, kmPerlat, PxPerKm);
- //Console.WriteLine(EW + "EW|NS" + NS);
- //Console.WriteLine(RGEW + "RGEW|RGNS" + RGNS);
- using Bitmap bitmap = new Bitmap(EW, NS);//位图大小东西南北界
- using (Graphics g = Graphics.FromImage(bitmap))
- {
- g.Clear(Color.White); // 使用Clear方法填充背景色
- }
- using Graphics graphics = Graphics.FromImage(bitmap);
- for (int i = 0; i < ACC.Length; i++)
- {
- int penWidth = math.max(EW, NS) / 500;
- Color colorThis = Color.White;
- if (ACC[i] >= 0)
- {
- colorThis = color[ACC[i] % (color.Count)];
- }
- using Pen Pen = new Pen(Color.Black, penWidth);
- //Rectangle rg = new Rectangle(0, 0, math.max(EW, NS) / 300, math.max(EW, NS) / 300);
- //float RGsize = math.max(EW, NS) / 300;
- graphics.DrawRectangle(Pen, LonToPx(UnitsP[i][0], W, kmPerlon, PxPerKm) - (int)(0.5 * RGEW), LatToPx(UnitsP[i][1], N, kmPerlat, PxPerKm) - (int)(0.5 * RGNS), RGEW, RGNS);
- using Brush BrushT = new SolidBrush(colorThis);
- graphics.FillRectangle(BrushT, LonToPx(UnitsP[i][0], W, kmPerlon, PxPerKm) - (int)(0.5 * RGEW), LatToPx(UnitsP[i][1], N, kmPerlat, PxPerKm) - (int)(0.5 * RGNS), RGEW, RGNS);
- }
- for (int i = 1; i < poly.Count; i++)
- {
- int penWidth = math.max(EW, NS) / 250;
- using Pen Pen = new Pen(Color.Black, penWidth);
- Point Point1 = new Point(LonToPx(poly[i - 1][0], W, kmPerlon, PxPerKm), LatToPx(poly[i - 1][1], N, kmPerlat, PxPerKm));
- Point Point2 = new Point(LonToPx(poly[i][0], W, kmPerlon, PxPerKm), LatToPx(poly[i][1], N, kmPerlat, PxPerKm));
- graphics.DrawLine(Pen, Point1, Point2);
- }
- bitmap.Save(name + ".jpeg");
- Console.WriteLine(ACC.Length + "个网格已画制并保存到" + name + ".jpeg文件中||" + EW + "EW|NS" + NS);
- }
- public static List<double[]> CirclePoint(double[] Center, double r, int pointnumber, double startPoint, double H,bool isClockWise)
- //经纬度,半径(km),点数量,起始点(角度,正北为0,顺时针),海拔高度
- {
- List<double[]> CirclePoint = new List<double[]>();
- double kmPerlat = 111.1;
- double kmPerlon = kmPerlat * Math.Cos((Math.PI / 180) * Center[1]);
- double Rlat = r / kmPerlat;
- double Rlon = r / kmPerlon;
- double DevideAngleRad = 2 * Math.PI / pointnumber;
- double startPointRad = startPoint * (Math.PI / 180);
- int k = 1;
- if(isClockWise==false)
- { k = -1; }
- for (int i = 0; i < pointnumber; i++)
- {
- double AngleRad = (startPointRad + k*i * DevideAngleRad) % (2 * Math.PI);
- double pointLon = Center[0] + Math.Sin(AngleRad) * Rlon;
- double pointLat = Center[1] + Math.Cos(AngleRad) * Rlat;
- double[] point = { pointLon, pointLat, H };
- CirclePoint.Add(point);
- }
- return CirclePoint;
- }
- public static void PostProcessTotal(double ResultStartTime,double ResultEndTime, TXResult TXR, List<object[]>Unit, List<object[]> GridResult, List<object[]> NetResult,int FirstOne,double Timestep,string CalculateName)
- //结果统计开始时间、结束时间
- {
- List<int> netBaseList = (List<int>)NetResult[0][1];
- int[] maxSingle = new int[netBaseList.Count];
- if (NetResult.Count > 0)
- {
- //List<int> netBaseList = (List<int>)NetResult[0][1];
-
- int maxTotal = 0;
- double TimeConnected = 0;
- for(int k = 0;k< netBaseList.Count;k++)
- {
- maxSingle[k] = 0;
- }
- double[] FulRatio = new double[NetResult.Count];
- for (int i = 0; i < NetResult.Count; i++)//读取每时步结果
- {
- List<int> ConnectedSingle = (List<int>)NetResult[i][2];
- if (ConnectedSingle[FirstOne] > 0)
- {
- TXR.FirstOneArriveTime = (double)NetResult[i][0];//记录最早连接的时间
- break;
- }
- }
- int iStart = (int)((ResultStartTime+0.5*Timestep) / Timestep);
- int iEnd = (int)((ResultEndTime+0.5 * Timestep) / Timestep);
- for (int i = 0; i < NetResult.Count; i++)//读取每时步结果
- {
- FulRatio[i] = (double)NetResult[i][5];
- List<int> ConnectedSingle = (List<int>)NetResult[i][2];
- //List < double>BaseFull= (List<double>)NetResult[i][4];
- for (int j=0;j< ConnectedSingle.Count;j++)
- {
- if (ConnectedSingle[j]> maxSingle[j]) { maxSingle[j] = ConnectedSingle[j]; }
- }
- if(maxTotal < (int)NetResult[i][3])
- { maxTotal = (int)NetResult[i][3]; }
- if (i>=iStart && i<=iEnd &&(int)NetResult[i][3]>0)
- {
- if(NetResult.Count >1 && i==iStart)
- {
- TimeConnected += (iStart*Timestep-ResultStartTime)+0.5 * Timestep;
- }
- else if(NetResult.Count > 1 && i == iEnd)
- {
- TimeConnected +=(ResultEndTime-iEnd*Timestep) + 0.5 * Timestep;
- }
- else
- {
- { TimeConnected += Timestep; }
- }
- }
- }
- int maxmaxSingle = maxSingle.Max();
- double FulRatioAve = FulRatio.Average();
- TXR.SingleMaxConnect = maxmaxSingle;
- TXR.MaxTotalConnect = maxTotal;
- TXR.ConnectTimeRatio = TimeConnected/(ResultEndTime-ResultStartTime);
- TXR.UnitFulfilledRatio = FulRatioAve;
- }
- if (GridResult.Count > 0)
- {
- double FirstMaxCover = 0;
- for (int i = 0; i < GridResult.Count; i++)//读取每时步结果
- {
- if ((double)GridResult[i][3] >= 1)
- {
- TXR.FullCoverTime = (double)GridResult[i][0];//记录最早100%连接的时间
- break;
- }
- }
- double[] TotalCover = new double[GridResult.Count];
- for (int i = 0; i < GridResult.Count; i++)//读取每时步结果
- {
- double FirstCover = ((double[])GridResult[i][2])[FirstOne];
- if (FirstMaxCover < FirstCover)
- { FirstMaxCover =FirstCover; }
- TotalCover[i] = (double)GridResult[i][4];
- }
- double AveTotalCover = TotalCover.Average();
- TXR.FirstOneMaxCover = FirstMaxCover;
- TXR.AverageTotalCover = AveTotalCover;
- }
- Console.WriteLine("准备时间:" + TXR.FirstOneReadyTime+"s||到达任务区域时间:"+TXR.FirstOneArriveTime+ "s||首架次覆盖范围最大值:"+ TXR.FirstOneMaxCover
- +"km²||最大单架接入用户数:"+ TXR.SingleMaxConnect+"个||第一次完全覆盖时间:"+ TXR.FullCoverTime+"s||平均总覆盖面积:"
- + TXR.AverageTotalCover + "km²||同时连接最大用户数量:"+ TXR.MaxTotalConnect+ "个||保持至少一个单位有通信情况下的时间比例:"+
- (TXR.ConnectTimeRatio*100)+ "%||能满足流量需求的单位比例:"+ (TXR.UnitFulfilledRatio*100)+"%");
- string csvFilePath = CalculateName + "/应急通信计算报告.csv";
- using (var writer = new StreamWriter(csvFilePath, Encoding.UTF8, new FileStreamOptions{Access = FileAccess.Write,
- Mode = FileMode.Create,
- Share = FileShare.None,
- Options = FileOptions.None}))
- {
- writer.WriteLine(String.Format("{0} ,{1}", "指标名", "数值"));
- writer.WriteLine(String.Format("{0} ,{1}", "首架次出动准备时间(秒)", TXR.FirstOneReadyTime));
- writer.WriteLine(String.Format("{0} ,{1}", "首架次飞抵时间(秒)", TXR.FirstOneArriveTime));
- writer.WriteLine(String.Format("{0} ,{1}", "首架次最大单次覆盖范围(平方千米)", TXR.FirstOneMaxCover));
- writer.WriteLine(String.Format("{0} ,{1}", "任务区域全覆盖实现时间(秒)", TXR.FullCoverTime));
- writer.WriteLine(String.Format("{0} ,{1}", "平均覆盖地面总面积(平方千米)", TXR.AverageTotalCover));
- writer.WriteLine(String.Format("{0} ,{1}", "最大单次总接入数量", TXR.MaxTotalConnect));
- writer.WriteLine(String.Format("{0} ,{1}", "给定时间内持续保障率(%)", TXR.ConnectTimeRatio * 100));
- writer.WriteLine(String.Format("{0} ,{1}", "满足通信速率要求的用户比例(%)", TXR.UnitFulfilledRatio * 100));
- writer.WriteLine(String.Format("{0} ,{1}", "通信稳定性", TXR.Stability));
- writer.WriteLine(String.Format("{0} ,{1}", "鲁棒性", TXR.Robustness));
- writer.WriteLine(String.Format("{0} ,{1}", "安全性", TXR.Security));
- writer.WriteLine(String.Format("{0}", " "));
- writer.WriteLine(String.Format("{0} ,{1}", "基站名称", "单基站最大接入数量"));
-
- for (int i = 0; i < netBaseList.Count; i++)
- { writer.WriteLine(String.Format("{0} ,{1}", (string)(Unit[netBaseList[i]][1]), maxSingle[i])); }
- }
- }
- public static List<double[]> Hover(double[]Location,double Direction,double H,bool isRealHeight,double EnterDistance)
- {
- double kmPerlat = 111.1;
- double kmPerlon = kmPerlat * Math.Cos((Math.PI / 180) * Location[1]);
- double Dlat = EnterDistance / kmPerlat;
- double Dlon = EnterDistance / kmPerlon;
- double DirectionRad = Direction * (Math.PI / 180);
- double EnterLon = Location[0] - Math.Sin(DirectionRad) * Dlon;
- double EnterLat = Location[1] - Math.Cos(DirectionRad) * Dlat;
- double H1 = H;
- if (isRealHeight) { H1 += HeightLL(Location[0], Location[1]); }
- double[] Point1 = { Location[0], Location[1], H1 };
- double[]Point0= { EnterLon, EnterLat, H1 };
- List<double[]> Hover = new List<double[]>();
- Hover.Add(Point0);
- Hover.Add(Point1);
- return Hover;
- }
- }
- }
|