// interval: 绕射点间隔
        public List <Vector3D> DiffractedRay_VerticalSide(Point originPoint, Vector3D dir, int interval)
        {
            // 返回值
            List <Vector3D> refDirs = new List <Vector3D>();

            // 旋转轴
            Vector3D axis = new Vector3D(0, 0, 0);

            if (dir.ZComponent < 0)  // 入射线方向朝下
            {
                axis.ZComponent = -1;
            }
            else
            {
                axis.ZComponent = 1;
            }

            // 判断是否射入建筑物内
            List <Point> polygonPoints = BuildingGrid3D.getBuildingVertex(this.nodeInfo.buildingID);
            int          id            = 0; // 记录交点的下标
            int          n             = polygonPoints.Count;

            for (int i = 0; i < polygonPoints.Count; i++)
            {
                if ((Math.Abs(this.nodeInfo.CrossPoint.X - polygonPoints[i].X) < 0.5 && Math.Abs(this.nodeInfo.CrossPoint.Y - polygonPoints[i].Y) < 0.5))
                {
                    id = i;
                    break;
                }
            }

            Vector3D nor1 = Vector3D.constructVector(polygonPoints[id], polygonPoints[(id + 1) % n]);
            Vector3D nor2 = Vector3D.constructVector(polygonPoints[id], polygonPoints[(id - 1 + n) % n]);

            nor1.ZComponent = 0;
            nor2.ZComponent = 0;

            for (int i = 0; i < 360; i += interval)
            {
                Vector3D dif = RotateAroundAxisZ((double)i * Math.PI / 180.0, dir);
                if (dif.dotProduct(nor1) > 0 && dif.dotProduct(nor2) > 0)  // 与该顶点的两条边夹角都为锐角,则射入建筑物内
                {
                    continue;
                }
                refDirs.Add(dif);
            }
            return(refDirs);
        }
        // interval: 绕射点间隔
        public List <Vector3D> DiffractedRay_HorizontalSide(Point originPoint, Vector3D dir, int interval)
        {
            // 返回值
            List <Vector3D> refDirs = new List <Vector3D>();

            // 构造被绕射边向量,选择与入射线方向相同的那个方向
            Vector3D edgeDir = Vector3D.constructVector(this.nodeInfo.SideFromPoint, this.nodeInfo.SideToPoint);

            if (edgeDir.dotProduct(dir) < 0)
            {
                edgeDir = new Vector3D(-edgeDir.XComponent, -edgeDir.YComponent, -edgeDir.ZComponent);
            }
            edgeDir.unit();

            // 用于判断是否射入建筑物内
            List <Point> polygonPoints = BuildingGrid3D.getBuildingVertex(this.nodeInfo.buildingID);

            Vector3D down = new Vector3D(0, 0, -1);
            Vector2D v1   = new Vector2D(this.nodeInfo.SideFromPoint.X, this.nodeInfo.SideFromPoint.Y);
            Vector2D v2   = new Vector2D(this.nodeInfo.SideToPoint.X, this.nodeInfo.SideToPoint.Y);
            Line2D   seg  = new Line2D(v1, v2);
            Vector2D p    = new Vector2D();
            Vector2D side = new Vector2D();

            seg.getPtNorm(out p, out side);
            Vector3D side1 = new Vector3D(-side.x, -side.y, 0);

            for (int i = 0; i < 360; i += interval)
            {
                Vector3D dif = RotateAroundAxisAny(edgeDir, (double)i * Math.PI / 180.0, dir);
                if (dif.dotProduct(down) > 0 && dif.dotProduct(side1) > 0)  // 与顶面和侧面的夹角都为锐角,则射入建筑物内
                {
                    continue;
                }
                refDirs.Add(dif);
            }

            return(refDirs);
        }
Beispiel #3
0
        /// <summary>
        /// 计算小区室内传播路径损耗
        /// </summary>
        /// <param name="indoorstart">室内入射点</param>
        /// <param name="indoorend">结束点,有可能不在室内</param>
        public void CalcAndMergeBGridStrength(double rayAzimuth, double rayInclination, List <NodeInfo> rays, Point indoorstart, Point indoorend)
        {
            NodeInfo ray        = rays.Last();
            int      buildingID = ray.buildingID;

            double[] receiveList = calcRayStrength(rayAzimuth, rayInclination, ref rays);
            double   dbminner    = convertw2dbm(receiveList[0]) - transmissionLoss(0);

            if (dbminner < -130)
            {
                return;
            }

            double pwr = 0;

            // 室内
            Grid3D curGrid3D;
            double dis     = 0.0;
            double dbmgrid = 0.0;

            LineCrossGrid3D linecrossgrid3d = new LineCrossGrid3D(indoorstart, indoorend);

            while ((curGrid3D = linecrossgrid3d.getNextCrossGrid3D(ref dis)) != null)
            {
                if (!BuildingGrid3D.isBuildingExistGrid3D(buildingID, curGrid3D.gxid, curGrid3D.gyid, curGrid3D.gzid))
                {
                    break;
                }
                dbmgrid = dbminner - distanceLoss(receiveList[1], dis);
                if (dbmgrid < -130)
                {
                    return;
                }
                pwr = convertdbm2w(dbmgrid);

                mergeIndoorGridStrength(curGrid3D, rays, pwr, buildingID);
            }
        }
        double constraint_low_bound   = 0.02;   // 策略3的控制参数

        //public Result smoothBuildingPoints()
        //{
        //    IbatisHelper.ExecuteDelete("DeleteBuildingVertex", null);

        //    DataTable dt = new DataTable();
        //    dt.Columns.Add("BuildingID", System.Type.GetType("System.Int32"));
        //    dt.Columns.Add("VertexLong", System.Type.GetType("System.Double"));
        //    dt.Columns.Add("VertexLat", System.Type.GetType("System.Double"));
        //    dt.Columns.Add("VertexX", System.Type.GetType("System.Double"));
        //    dt.Columns.Add("VertexY", System.Type.GetType("System.Double"));
        //    dt.Columns.Add("VIndex", System.Type.GetType("System.Int16"));

        //    Hashtable ht = new Hashtable();
        //    int pageindex = 0;
        //    int pagesize = 10000;
        //    ht["pageindex"] = pageindex;
        //    ht["pagesize"] = pagesize;
        //    BuildingGrid3D.constructBuildingVertexOriginalByBatch(pageParam: ht);
        //    while (BuildingGrid3D.buildingVertexOriginal.Count > 0)
        //    {
        //        int minBid, maxBid;
        //        BuildingGrid3D.getAllBuildingIDRange(out minBid, out maxBid);

        //        for (int i = minBid; i <= maxBid; i++)
        //        {
        //            List<LTE.Geometric.Point> bpoints = BuildingGrid3D.getBuildingVertexOriginal(i);

        //            List<LTE.Geometric.Point> ps = Process(ref bpoints);  // 2018-05-08
        //            if (ps.Count < 20)
        //                ps = bpoints;

        //            for (int j = 0; j < ps.Count; j++)
        //            {
        //                //使用proj.net库转换坐标,by JinHaijia
        //                LTE.Geometric.Point pCopy=new LTE.Geometric.Point(ps[j]);
        //                pCopy = LTE.Utils.PointConvertByProj.Instance.GetGeoPoint(pCopy);

        //                //旧版使用arcgis接口转换坐标
        //                //ESRI.ArcGIS.Geometry.IPoint p = GeometryUtilities.ConstructPoint2D(ps[j].X, ps[j].Y);
        //                //PointConvert.Instance.GetGeoPoint(p);

        //                //System.Diagnostics.Debug.WriteLine("transfNew long:" + pCopy.X + " latitude:" + pCopy.Y);
        //                //System.Diagnostics.Debug.WriteLine("transfOld long:" + p.X + " latitude:" + p.Y);
        //                //System.Diagnostics.Debug.WriteLine("_________");

        //                DataRow dr = dt.NewRow();
        //                dr["BuildingID"] = i;
        //                dr["VertexLong"] = pCopy.X;
        //                dr["VertexLat"] = pCopy.Y;
        //                dr["VertexX"] = ps[j].X;
        //                dr["VertexY"] = ps[j].Y;
        //                dr["VIndex"] = j;
        //                dt.Rows.Add(dr);
        //            }
        //            if (dt.Rows.Count >= 5000)
        //            {
        //                DataUtil.BCPDataTableImport(dt, "tbBuildingVertex");
        //                dt.Clear();
        //            }
        //        }
        //        DataUtil.BCPDataTableImport(dt, "tbBuildingVertex");
        //        dt.Clear();
        //        BuildingGrid3D.clearBuildingVertexOriginal();
        //        ht["pageindex"] = ++pageindex;
        //        BuildingGrid3D.constructBuildingVertexOriginalByBatch(pageParam: ht);
        //    }
        //    return new Result(true,"建筑物顶点平滑完成");
        //}


        public Result smoothBuildingPoints()
        {
            BuildingGrid3D.constructBuildingVertexOriginal();
            int minBid, maxBid;

            BuildingGrid3D.getAllBuildingIDRange(out minBid, out maxBid);

            DataTable dt = new DataTable();

            dt.Columns.Add("BuildingID", System.Type.GetType("System.Int32"));
            dt.Columns.Add("VertexLong", System.Type.GetType("System.Double"));
            dt.Columns.Add("VertexLat", System.Type.GetType("System.Double"));
            dt.Columns.Add("VertexX", System.Type.GetType("System.Double"));
            dt.Columns.Add("VertexY", System.Type.GetType("System.Double"));
            dt.Columns.Add("VIndex", System.Type.GetType("System.Int16"));

            try
            {
                IbatisHelper.ExecuteDelete("DeleteBuildingVertex", null);
            }
            catch (Exception e)
            {
                return(new Result(false, e.ToString()));
            }

            for (int i = minBid; i <= maxBid; i++)
            {
                List <LTE.Geometric.Point> bpoints = BuildingGrid3D.getBuildingVertexOriginal(i);

                List <LTE.Geometric.Point> ps = Process(ref bpoints);  // 2018-05-08


                if (ps.Count < 20)
                {
                    ps = bpoints;
                }

                for (int j = 0; j < ps.Count; j++)
                {
                    LTE.Geometric.Point p     = new Geometric.Point(ps[j].X, ps[j].Y, 0);
                    LTE.Geometric.Point pCopy = new LTE.Geometric.Point(ps[j]);
                    p = LTE.Utils.PointConvertByProj.Instance.GetGeoPoint(p);

                    DataRow dr = dt.NewRow();
                    dr["BuildingID"] = i;
                    dr["VertexLong"] = p.X;
                    dr["VertexLat"]  = p.Y;
                    dr["VertexX"]    = ps[j].X;
                    dr["VertexY"]    = ps[j].Y;
                    dr["VIndex"]     = j;
                    dt.Rows.Add(dr);
                }
                if (dt.Rows.Count >= 5000)
                {
                    DataUtil.BCPDataTableImport(dt, "tbBuildingVertex");
                    dt.Clear();
                }
            }
            DataUtil.BCPDataTableImport(dt, "tbBuildingVertex");
            dt.Clear();
            BuildingGrid3D.clearBuildingVertexOriginal();

            return(new Result(true));
        }
 public BuildingGrid3D()
 {
     instance = this;
 }