// getTb:读数据库的sql // flag:false--操作tbGridPathloss, true--操作tbBuildingGridPathloss // 只有半径比较大的时候才会用到,因为一次算不完 private void mergePwr1(double EIRP, string getTb, bool flag, int eNodeB, int CI) { Hashtable ht = new Hashtable(); ht["CI"] = CI; ht["eNodeB"] = eNodeB; DataTable tb = IbatisHelper.ExecuteQueryForDataTable(getTb, ht); GridCover gc = GridCover.getInstance(); if (flag) { gc.deleteBuildingCover(ht); } else { gc.deleteGroundCover(ht); } Dictionary <string, GridStrength> gridStrengths = new Dictionary <string, GridStrength>(); foreach (DataRow dataRow in tb.Rows) { #region 读入数据,按栅格分组,合并 int GXID = int.Parse(dataRow["GXID"].ToString()); int GYID = int.Parse(dataRow["GYID"].ToString()); int GZID = 0; if (flag) { GZID = int.Parse(dataRow["Level"].ToString()); } string key = String.Format("{0},{1},{2}", GXID, GYID, GZID); if (!gridStrengths.ContainsKey(key)) { GridStrength gs = new GridStrength(); gs.GXID = GXID; gs.GYID = GYID; gs.Level = GZID; gs.eNodeB = int.Parse(dataRow["eNodeB"].ToString()); gs.CI = int.Parse(dataRow["CI"].ToString()); if (dataRow["FieldIntensity"].ToString() != "") { gs.FieldIntensity = double.Parse(dataRow["FieldIntensity"].ToString()); } gs.DirectNum = int.Parse(dataRow["DirectPwrNum"].ToString()); gs.DirectPwrW = double.Parse(dataRow["DirectPwrW"].ToString()); gs.MaxDirectPwrW = double.Parse(dataRow["MaxDirectPwrW"].ToString()); gs.RefNum = int.Parse(dataRow["RefPwrNum"].ToString()); gs.RefPwrW = double.Parse(dataRow["RefPwrW"].ToString()); gs.MaxRefPwrW = double.Parse(dataRow["MaxRefPwrW"].ToString()); gs.RefBuildingID = dataRow["RefBuildingID"].ToString(); gs.DiffNum = int.Parse(dataRow["DiffNum"].ToString()); gs.DiffPwrW = double.Parse(dataRow["DiffPwrW"].ToString()); gs.MaxDiffPwrW = double.Parse(dataRow["MaxDiffPwrW"].ToString()); gs.DiffBuildingID = dataRow["DiffBuildingID"].ToString(); gs.BTSGridDistance = double.Parse(dataRow["BTSGridDistance"].ToString()); //gs.ReceivedPowerW = double.Parse(dataRow["ReceivedPowerW"].ToString()); //gs.ReceivedPowerdbm = double.Parse(dataRow["ReceivedPowerdbm"].ToString()); //gs.PathLoss = double.Parse(dataRow["PathLoss"].ToString()); if (flag) { gs.TransNum = int.Parse(dataRow["TransNum"].ToString()); gs.TransPwrW = double.Parse(dataRow["TransPwrW"].ToString()); gs.MaxTransPwrW = double.Parse(dataRow["MaxTransPwrW"].ToString()); gs.TransmitBuildingID = dataRow["TransmitBuildingID"].ToString(); } else { gs.TransNum = 0; gs.TransPwrW = 0; gs.MaxTransPwrW = 0; gs.TransmitBuildingID = ""; } gridStrengths.Add(key, gs); } else { GridStrength ogs = gridStrengths[key]; ogs.DirectNum += int.Parse(dataRow["DirectPwrNum"].ToString()); double pwr = double.Parse(dataRow["DirectPwrW"].ToString()); ogs.DirectPwrW += double.Parse(dataRow["DirectPwrW"].ToString()); if (ogs.MaxDirectPwrW < double.Parse(dataRow["MaxDirectPwrW"].ToString())) { ogs.MaxDirectPwrW = double.Parse(dataRow["MaxDirectPwrW"].ToString()); } ogs.RefBuildingID += dataRow["RefBuildingID"].ToString(); ogs.RefNum += int.Parse(dataRow["RefPwrNum"].ToString()); ogs.RefPwrW += double.Parse(dataRow["RefPwrW"].ToString()); if (ogs.MaxRefPwrW < double.Parse(dataRow["MaxRefPwrW"].ToString())) { ogs.MaxRefPwrW = double.Parse(dataRow["MaxRefPwrW"].ToString()); } ogs.DiffNum += int.Parse(dataRow["DiffNum"].ToString()); ogs.DiffPwrW += double.Parse(dataRow["DiffPwrW"].ToString()); ogs.DiffBuildingID += dataRow["DiffBuildingID"].ToString(); if (ogs.MaxDiffPwrW < double.Parse(dataRow["MaxDiffPwrW"].ToString())) { ogs.MaxDiffPwrW = double.Parse(dataRow["MaxDiffPwrW"].ToString()); } if (flag) { ogs.TransNum += int.Parse(dataRow["TransNum"].ToString()); ogs.TransPwrW += double.Parse(dataRow["TransPwrW"].ToString()); ogs.TransmitBuildingID += dataRow["TransmitBuildingID"].ToString(); if (ogs.MaxTransPwrW < double.Parse(dataRow["MaxTransPwrW"].ToString())) { ogs.MaxTransPwrW = double.Parse(dataRow["MaxTransPwrW"].ToString()); } } //dictionary不能自动更新 gridStrengths[key] = ogs; } #endregion if (gridStrengths.Count > 30000) { # region 计算栅格最终功率 foreach (var k in gridStrengths.Keys.ToArray()) { GridStrength ogs = gridStrengths[k]; double p = ogs.DirectPwrW + ogs.DiffPwrW + ogs.RefPwrW + ogs.TransPwrW; if (p > 0) { ogs.ReceivedPowerW = p; } ogs.ReceivedPowerdbm = convertw2dbm(ogs.ReceivedPowerW); ogs.PathLoss = EIRP - ogs.ReceivedPowerdbm; //反射、绕射建筑物id去重 ogs.RefBuildingID = DistinctStringArray(ogs.RefBuildingID.Split(';')); ogs.DiffBuildingID = DistinctStringArray(ogs.DiffBuildingID.Split(';')); ogs.TransmitBuildingID = DistinctStringArray(ogs.TransmitBuildingID.Split(';')); //dictionary 不能自动更新 gridStrengths[k] = ogs; } #endregion #region 写入数据库 gc.convertToDt(gridStrengths); if (flag) { gc.writeBuildingCover(ht); gc.clearBuilding(); } else { gc.wirteGroundCover(ht); gc.clearGround(); } #endregion gridStrengths.Clear(); } }
/// <summary> /// 如果数据库表 tbAdjCoefficient 中有校正系数时,则界面中的校正系数仅仅被传入,而不会在计算场强中用到 /// </summary> /// <returns></returns> public Result calc(bool loadInfo = false) { int eNodeB = 0, CI = 0; string cellType = ""; Result rt = validateCell(ref eNodeB, ref CI, ref cellType); if (!rt.ok) { return(rt); } CellInfo cellInfo = new CellInfo(this.cellName, eNodeB, CI, this.directCoeff, this.reflectCoeff, this.diffractCoeff, this.diffractCoeff2); double fromAngle = cellInfo.Azimuth - this.incrementAngle; double toAngle = cellInfo.Azimuth + this.incrementAngle; ////指定最大覆盖半径 //int maxCoverageRadius = 15000; //this.distance = Math.Min(this.distance, maxCoverageRadius); // 删除旧的接收功率数据 Hashtable ht = new Hashtable(); ht["CI"] = CI; ht["eNodeB"] = eNodeB; GridCover gc = GridCover.getInstance(); gc.deleteBuildingCover(ht); gc.deleteGroundCover(ht); // 计算方案 int threadCnt = 0, batchNum = 0, flag = 0; bool ok = howCalc(fromAngle, toAngle, ref threadCnt, ref batchNum, ref flag); this.threadNum = 2; threadCnt = 2; // 不需要分批计算 if (ok) { List <ProcessArgs> paList = new List <ProcessArgs>(); bool reRay = false; // 是否需要进行二次投射,即读取前一批覆盖计算中出界的射线,并对其进行射线跟踪 bool recordReRay = false; // 是否需要记录当前批的出界射线 if (loadInfo) { return(parallelComputing(ref cellInfo, fromAngle, toAngle, eNodeB, CI, ref paList, reRay, recordReRay, false, false, LoadInfo.UserId.Value, LoadInfo.taskName.Value)); } else { return(parallelComputing(ref cellInfo, fromAngle, toAngle, eNodeB, CI, ref paList, reRay, recordReRay, false, false, -1, "default")); } // 小区覆盖计算 } // 需要分批计算 else { IbatisHelper.ExecuteDelete("deleteSpecifiedReRay", ht); // 建议计算方案:线程数:threadCnt, 批数 batchNum if (flag == 2) { this.threadNum = threadCnt; //double delta = (toAngle - fromAngle + 360) % 360 / batchNum; double delta = (toAngle - fromAngle) / batchNum; double startAngle = fromAngle; for (int currBatch = 1; currBatch <= batchNum; currBatch++) { //var batchTaskName = taskName + batchNum; fromAngle = (startAngle + (currBatch - 1) * delta + 360) % 360; toAngle = (fromAngle + delta + 360) % 360; List <ProcessArgs> paList = new List <ProcessArgs>(); bool reRay = false; // 是否需要进行二次投射,即读取前一批覆盖计算中出界的射线,并对其进行射线跟踪 if (currBatch > 1) // 当前不是第一批,就需要进行二次投射 { reRay = true; } bool recordReRay = false; // 是否需要记录当前批的出界射线 if (currBatch < batchNum) // 前批不是最后一批,则需记录当前批的出界射线,供下批二次投射 { recordReRay = true; } // 小区覆盖计算 Result result = parallelComputing(ref cellInfo, fromAngle, toAngle, eNodeB, CI, ref paList, reRay, recordReRay, false, false, LoadInfo.UserId.Value, LoadInfo.taskName.Value); if (!result.ok) { return(result); } // 分批计算的最后一批,需要对相同小区、相同栅格的功率进行合并 if (currBatch == batchNum) { mergePwr1(cellInfo.EIRP, "getPwrGround", false, eNodeB, CI); mergePwr1(cellInfo.EIRP, "getPwrBuilding", true, eNodeB, CI); } } return(new Result(true)); } // 建议计算方案:线程数:threadCnt else { this.threadNum = threadCnt; List <ProcessArgs> paList = new List <ProcessArgs>(); bool reRay = false; // 是否需要进行二次投射,即读取前一批覆盖计算中出界的射线,并对其进行射线跟踪 bool recordReRay = false; // 是否需要记录当前批的出界射线 return(parallelComputing(ref cellInfo, fromAngle, toAngle, eNodeB, CI, ref paList, reRay, recordReRay, false, false, LoadInfo.UserId.Value, LoadInfo.taskName.Value)); } } }