Пример #1
0
 private bool Init()
 {
     this.isCalc     = true;
     this.cur        = new Grid3D();
     this.line       = new Line();
     this.gridlength = GridHelper.getInstance().getAGridSize();
     this.vgridsize  = GridHelper.getInstance().getAGridVSize();
     return(!(this.gridlength < 0 || this.vgridsize < 0));
 }
Пример #2
0
 private bool Init()
 {
     this.isCalc      = false;
     this.cur         = new Grid3D();
     this.distance    = 0.0;
     this.line        = new Line();
     this.gridlength  = GridHelper.getInstance().getGGridSize();
     this.vgridsize   = GridHelper.getInstance().getGHeight();
     this.gbaseheight = GridHelper.getInstance().getGBaseHeight();
     return(!(this.gridlength < 0 || this.vgridsize < 0 || this.gbaseheight < 0));
 }
Пример #3
0
        /// <summary>
        /// 根据建筑物栅格ID获取范围内的地面栅格中心点
        /// </summary>
        /// <param name="gxid"></param>
        /// <param name="gyid"></param>
        /// <param name="gzid"></param>
        /// <returns></returns>
        public static Point getBGridCenter(int gxid, int gyid, int gzid)
        {
            string key = string.Format("{0},{1}", gxid, gyid);

            if (!ggrids.ContainsKey(key))
            {
                return(null);
            }
            Point ret = ggrids[key];

            ret.Z = GridHelper.getInstance().getGHeight() * (gzid - 1) + GridHelper.getInstance().getGBaseHeight();
            return(ret);
        }
Пример #4
0
        /// <summary>
        /// 获取扇区与地面栅格交集内的栅格中心点
        /// </summary>
        /// <param name="source"></param>
        /// <param name="distance">单位米</param>
        /// <param name="fromAngle">方位角</param>
        /// <param name="toAngle">方位角</param>
        /// <param name="DisAngle">需要排除的区域,角度坐标为极坐标, 如果没有要排除的区域,则传null</param>
        /// <returns></returns>
        public static List <Point> getGGridCenterBySector(Point source, double distance, double fromAngle, double toAngle, List <TriangleBound> DisAngle)
        {
            double minX = 0, minY = 0, maxX = 0, maxY = 0;

            GridHelper.getInstance().getMinXY(ref minX, ref minY);
            GridHelper.getInstance().getMaxXY(ref maxX, ref maxY);

            //边界,大地坐标
            double minx = Math.Max(minX, source.X - distance);
            double miny = Math.Max(minY, source.Y - distance);
            double maxx = Math.Min(maxX, source.X + distance);
            double maxy = Math.Min(maxY, source.Y + distance);

            //double minx = source.X - distance;
            //double miny = source.Y - distance;
            //double maxx = source.X + distance;
            //double maxy = source.Y + distance;
            //便于比较边缘地带
            distance += 0.1;

            double from = GeometricUtilities.ConvertGeometricArithmeticAngle(toAngle + 1);
            double to   = GeometricUtilities.ConvertGeometricArithmeticAngle(fromAngle - 1);

            from = GeometricUtilities.GetRadians(from);
            to   = GeometricUtilities.GetRadians(to);

            List <Point> ret = new List <Point>();
            Point        p;
            Polar        pr;

            foreach (KeyValuePair <string, Point> kv in ggrids)
            {
                p = kv.Value;
                if (p.X > minx && p.X < maxx && p.Y > miny && p.Y < maxy)
                {
                    pr = GeometricUtilities.getPolarCoord(source, p);

                    // 将位于扇区覆盖范围内,且不在建筑物内的地面栅格加进来 ;接收点加入海拔高度后,同时判断地面高度低于小区高度 ,jinhj
                    if (pr.r < distance && isInRange(pr.theta, from, to) && p.Z < source.Z)//&& !isInBuilding(p, ref DisAngle))
                    //if (pr.r < distance && isInRange(pr.theta, from, to) && !isInRange(pr, p, source, ref DisAngle))
                    {
                        ret.Add(p);
                    }
                }
            }
            return(ret);
        }
Пример #5
0
        /// <summary>
        /// 获取中心点在范围内的地面栅格中心点
        /// </summary>
        /// <returns></returns>
        public static int constructGGrids(ref Geometric.Point p1, ref Geometric.Point p2,
                                          ref Geometric.Point p3, ref Geometric.Point p4)
        {
            //Console.WriteLine("{0}", 1);
            ggrids = new Dictionary <string, Point>();

            Hashtable ht = new Hashtable();

            Grid3D gid1 = new Grid3D(), gid2 = new Grid3D(), gid3 = new Grid3D(), gid4 = new Grid3D();

            GridHelper.getInstance().PointXYZToGrid3D1(p1, ref gid1);
            GridHelper.getInstance().PointXYZToGrid3D1(p2, ref gid2);
            GridHelper.getInstance().PointXYZToGrid3D1(p3, ref gid3);
            GridHelper.getInstance().PointXYZToGrid3D1(p4, ref gid4);

            //Console.WriteLine("from: {0}", from * 180 / Math.PI);
            //Console.WriteLine("to: {0}", to * 180 / Math.PI);
            //Console.WriteLine("alpha: {0}", alpha * 180 / Math.PI);
            //Console.WriteLine("theta: {0}", theta * 180 / Math.PI);

            ht["x1"] = gid1.gxid;
            ht["x2"] = gid2.gxid;
            ht["x3"] = gid3.gxid;
            ht["x4"] = gid4.gxid;
            ht["y1"] = gid1.gyid;
            ht["y2"] = gid2.gyid;
            ht["y3"] = gid3.gyid;
            ht["y4"] = gid4.gyid;
            DataTable grids = IbatisHelper.ExecuteQueryForDataTable("getGroundGridsCenter", ht);
            //Console.WriteLine("{0}", grids.Rows.Count);
            double x, y, z;
            int    gxid, gyid;
            string key;

            for (int i = 0, cnt = grids.Rows.Count; i < cnt; i++)
            {
                gxid = Convert.ToInt32(grids.Rows[i]["GXID"]);
                gyid = Convert.ToInt32(grids.Rows[i]["GYID"]);
                x    = Convert.ToDouble(grids.Rows[i]["CX"]);
                y    = Convert.ToDouble(grids.Rows[i]["CY"]);
                z    = Convert.ToDouble(grids.Rows[i]["Dem"]);
                key  = string.Format("{0},{1}", gxid, gyid);
                ggrids.Add(key, new Point(x, y, z));
            }
            return(ggrids.Count);
        }
Пример #6
0
        /// <summary>
        /// 获取扇区内的点  2018.12.18
        /// </summary>
        /// <param name="source"></param>
        /// <param name="distance">单位米</param>
        /// <param name="fromAngle">方位角</param>
        /// <param name="toAngle">方位角</param>
        /// <param name="DisAngle">需要排除的区域,角度坐标为极坐标, 如果没有要排除的区域,则传null</param>
        /// <returns></returns>
        public static List <Point> getPointBySector(Point source, double distance, double fromAngle, double toAngle, double interval)
        {
            double minX = 0, minY = 0, maxX = 0, maxY = 0;

            GridHelper.getInstance().getMinXY(ref minX, ref minY);
            GridHelper.getInstance().getMaxXY(ref maxX, ref maxY);

            //边界,大地坐标
            double minx = Math.Max(minX, source.X - distance);
            double miny = Math.Max(minY, source.Y - distance);
            double maxx = Math.Min(maxX, source.X + distance);
            double maxy = Math.Min(maxY, source.Y + distance);

            //double minx = source.X - distance;
            //double miny = source.Y - distance;
            //double maxx = source.X + distance;
            //double maxy = source.Y + distance;
            //便于比较边缘地带
            distance += 0.1;

            double from = GeometricUtilities.ConvertGeometricArithmeticAngle(toAngle + 1);
            double to   = GeometricUtilities.ConvertGeometricArithmeticAngle(fromAngle - 1);

            from = GeometricUtilities.GetRadians(from);
            to   = GeometricUtilities.GetRadians(to);

            List <Point> ret = new List <Point>();

            for (double x = minx; x < maxx; x += interval)
            {
                for (double y = miny; y < maxy; y += interval)
                {
                    Point p  = new Point(x, y, 0);
                    Polar pr = GeometricUtilities.getPolarCoord(source, p);

                    // 将位于扇区覆盖范围内的点加进来
                    if (pr.r < distance && isInRange(pr.theta, from, to))
                    {
                        ret.Add(p);
                    }
                }
            }
            return(ret);
        }
Пример #7
0
        /// <summary>
        /// 根据覆盖扇形获取建筑物id
        /// </summary>
        /// <param name="source"></param>
        /// <param name="distance"></param>
        /// <param name="fromAngle"></param>
        /// <param name="toAngle"></param>
        /// <returns></returns>
        public static List <int> getBuildingIDBySector(Point source, double distance, double fromAngle, double toAngle)
        {
            double minX = 0, minY = 0, maxX = 0, maxY = 0;

            GridHelper.getInstance().getMinXY(ref minX, ref minY);
            GridHelper.getInstance().getMaxXY(ref maxX, ref maxY);

            //边界,大地坐标
            double minx = Math.Max(minX, source.X - distance);
            double miny = Math.Max(minY, source.Y - distance);
            double maxx = Math.Min(maxX, source.X + distance);
            double maxy = Math.Min(maxY, source.Y + distance);

            distance += 0.1;

            // (450-oldAngle)%360;
            double from = GeometricUtilities.ConvertGeometricArithmeticAngle(toAngle + 1);
            double to   = GeometricUtilities.ConvertGeometricArithmeticAngle(fromAngle - 1);

            //Console.WriteLine("from: {0}", from);
            //Console.WriteLine("to: {0}", to);

            from = GeometricUtilities.GetRadians(from);
            to   = GeometricUtilities.GetRadians(to);

            List <int> ret = new List <int>();
            Point      p;
            Polar      pr;

            foreach (KeyValuePair <int, Point> kv in buildingCenter)
            {
                p = kv.Value;
                if (p.X > minx && p.X < maxx && p.Y > miny && p.Y < maxy)
                {
                    pr = GeometricUtilities.getPolarCoord(source, p);
                    if (pr.r < distance && (isInRange(pr.theta, from, to))) // || isInRange(pr.theta + Math.PI * 2, from, to)))
                    {
                        ret.Add(Convert.ToInt32(kv.Key));
                    }
                }
            }
            return(ret);
        }
Пример #8
0
        /// <summary>
        /// 从数据库表tbGrid3D中取出所有符合条件的数据,并以GXID,GYID,GZID排序,组成空间网格集合
        /// </summary>
        /// <returns></returns>
        public static void constructGrid3D(ref Geometric.Point p1, ref Geometric.Point p2,
                                           ref Geometric.Point p3, ref Geometric.Point p4)
        {
            Hashtable para = new Hashtable();

            Grid3D gid1 = new Grid3D(), gid2 = new Grid3D(), gid3 = new Grid3D(), gid4 = new Grid3D();

            GridHelper.getInstance().PointXYZToGrid3D1(p1, ref gid1);
            GridHelper.getInstance().PointXYZToGrid3D1(p2, ref gid2);
            GridHelper.getInstance().PointXYZToGrid3D1(p3, ref gid3);
            GridHelper.getInstance().PointXYZToGrid3D1(p4, ref gid4);

            para["x1"] = gid1.gxid;
            para["x2"] = gid2.gxid;
            para["x3"] = gid3.gxid;
            para["x4"] = gid4.gxid;
            para["y1"] = gid1.gyid;
            para["y2"] = gid2.gyid;
            para["y3"] = gid3.gyid;
            para["y4"] = gid4.gyid;
            DataTable dt = IbatisHelper.ExecuteQueryForDataTable("GetBuildingGrid3D1", para);

            //Console.WriteLine(string.Format("{0} {1} {3}  {4} {5} {6} {7}", gid1.gxid, gid2.gxid, gid3.gxid, gid4.gxid, gid1.gyid, gid2.gyid, gid3.gyid, gid4.gyid);
            for (int i = 0; i < dt.Rows.Count; i++)//按行遍历DataTable
            {
                int buildingid = Convert.ToInt32(dt.Rows[i][0].ToString());
                //gxid,gyid,gzid
                string value = dt.Rows[i][1].ToString() + "," + dt.Rows[i][2].ToString() + "," + dt.Rows[i][3].ToString();
                if (bgrid3d.ContainsKey(buildingid))
                {
                    bgrid3d[buildingid].Add(value);
                }
                else
                {
                    List <string> list = new List <string>();
                    list.Add(value);
                    bgrid3d.Add(buildingid, list);
                }
            }
        }
Пример #9
0
        /// <summary>
        /// 构建建筑物底面点数据和中心点以及高度数据,顶面所有点
        /// </summary>
        public static void constructBuildingData(ref Geometric.Point p1, ref Geometric.Point p2,
                                                 ref Geometric.Point p3, ref Geometric.Point p4)
        {
            DateTime t0, t1, t2, t3;

            t0 = DateTime.Now;

            Hashtable ht = new Hashtable();

            Grid3D gid1 = new Grid3D(), gid2 = new Grid3D(), gid3 = new Grid3D(), gid4 = new Grid3D();

            GridHelper.getInstance().PointXYZToGrid3D1(p1, ref gid1);
            GridHelper.getInstance().PointXYZToGrid3D1(p2, ref gid2);
            GridHelper.getInstance().PointXYZToGrid3D1(p3, ref gid3);
            GridHelper.getInstance().PointXYZToGrid3D1(p4, ref gid4);

            ht["x1"] = gid1.gxid;
            ht["x2"] = gid2.gxid;
            ht["x3"] = gid3.gxid;
            ht["x4"] = gid4.gxid;
            ht["y1"] = gid1.gyid;
            ht["y2"] = gid2.gyid;
            ht["y3"] = gid3.gyid;
            ht["y4"] = gid4.gyid;

            DataTable dt = IbatisHelper.ExecuteQueryForDataTable("GetBuildingCenter", ht);

            int    bid;
            double x, y, z, altitude;

            for (int i = 0; i < dt.Rows.Count; i++)//按行遍历DataTable
            {
                bid = Convert.ToInt32(dt.Rows[i]["BuildingID"]);
                if (bid > maxID)
                {
                    maxID = bid;
                }
                if (bid < minID)
                {
                    minID = bid;
                }
                x        = Convert.ToDouble(dt.Rows[i]["BCenterX"]);
                y        = Convert.ToDouble(dt.Rows[i]["BCenterY"]);
                z        = Convert.ToDouble(dt.Rows[i]["BHeight"]);
                altitude = Convert.ToDouble(dt.Rows[i]["BAltitude"]); // 地形
                buildingCenter.Add(bid, new Point(x, y, 0));
                buildingHeight.Add(bid, z + altitude);                // 地形
                buildingAltitude.Add(bid, altitude);                  // 地形
            }

            t1 = DateTime.Now;

            dt = IbatisHelper.ExecuteQueryForDataTable("GetBuildingVertex", ht);
            List <Point> vcollection;
            Point        t;

            //string path = @"f:\t2.txt";
            //StreamWriter sw = File.CreateText(path);

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                bid = Convert.ToInt32(dt.Rows[i]["BuildingID"]);
                x   = Convert.ToDouble(dt.Rows[i]["VertexX"]);
                y   = Convert.ToDouble(dt.Rows[i]["VertexY"]);
                t   = new Point(x, y, 0);

                if (buildingVertex.ContainsKey(bid))
                {
                    buildingVertex[bid].Add(t);
                }
                else
                {
                    vcollection = new List <Point>();
                    vcollection.Add(t);
                    buildingVertex.Add(bid, vcollection);
                }
            }
            //sw.Close();
            t2 = DateTime.Now;

            dt = IbatisHelper.ExecuteQueryForDataTable("getBuildingTopVertex", ht);
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                bid = Convert.ToInt32(dt.Rows[i]["BuildingID"]);
                x   = Convert.ToDouble(dt.Rows[i]["CX"]);
                y   = Convert.ToDouble(dt.Rows[i]["CY"]);
                z   = buildingHeight[bid];
                t   = new Point(x, y, z);

                //sw.Write(bid + ": " + c.X + " " + c.Y + "\n");

                if (buildingTopVertex.ContainsKey(bid))
                {
                    buildingTopVertex[bid].Add(t);
                }
                else
                {
                    vcollection = new List <Point>();
                    vcollection.Add(t);
                    buildingTopVertex.Add(bid, vcollection);
                }
            }
            //sw.Close();
            t3 = DateTime.Now;

            Console.WriteLine(string.Format("建筑物底面中心:{0}秒", (t1 - t0).TotalMilliseconds / 1000));
            Console.WriteLine(string.Format("建筑物底面顶点:{0}秒", (t2 - t1).TotalMilliseconds / 1000));
            Console.WriteLine(string.Format("建筑物顶面顶点:{0}", (t3 - t2).TotalMilliseconds / 1000));
        }
Пример #10
0
        /// <summary>
        /// 构造函数,参数为大地坐标
        /// </summary>
        /// <param name="start">大地坐标</param>
        /// <param name="end">大地坐标</param>
        public LineCrossGrid3D(Point start, Point end)
        {
            this.isCalc = this.Init();
            if (!this.isCalc)
            {
                return;
            }
            GridHelper.getInstance().getMaxGGridXY(ref this.maxgxid, ref this.maxgyid);

            this.isCalc = !PointComparer.Equals1(start, end) && GridHelper.getInstance().PointXYZToGrid3D(start, ref this.cur);
            if (!this.isCalc)
            {
                return;
            }

            Vector3D dir = Vector3D.constructVector(start, end);

            this.line.setLine(start, dir);

            this.stepx = (this.line.paraEqua.X < 0 ? -1 : 1);
            this.stepy = (this.line.paraEqua.Y < 0 ? -1 : 1);
            this.stepz = (this.line.paraEqua.Z < 0 ? -1 : 1);

            Point ingrid = new Point();

            this.isCalc = GridHelper.getInstance().PointXYZInGrid3D(start, ref ingrid);
            if (!this.isCalc)
            {
                return;
            }

            if (Math.Round(this.line.paraEqua.X, 3) == 0)
            {
                this.tx = this.dx = maxlength;
            }
            else if (this.line.paraEqua.X > 0)
            {
                this.dx = this.gridlength / this.line.paraEqua.X;
                this.tx = (this.gridlength - ingrid.X) / this.line.paraEqua.X;
            }
            else
            {
                this.dx = this.gridlength / (0 - this.line.paraEqua.X);
                this.tx = ingrid.X / (0 - this.line.paraEqua.X);
            }

            if (Math.Round(this.line.paraEqua.Y, 3) == 0)
            {
                this.ty = this.dy = maxlength;
            }
            else if (this.line.paraEqua.Y > 0)
            {
                this.dy = this.gridlength / this.line.paraEqua.Y;
                this.ty = (this.gridlength - ingrid.Y) / this.line.paraEqua.Y;
            }
            else
            {
                this.dy = this.gridlength / (0 - this.line.paraEqua.Y);
                this.ty = ingrid.Y / (0 - this.line.paraEqua.Y);
            }

            if (Math.Round(this.line.paraEqua.Z, 3) == 0)
            {
                this.tz = this.dz = maxlength;//因为tz太大,dz随便定义
            }
            else if (this.line.paraEqua.Z > 0)
            {
                this.dz = this.vgridsize / this.line.paraEqua.Z;
                this.tz = (this.vgridsize - ingrid.Z) / this.line.paraEqua.Z;
            }
            else if (this.line.paraEqua.Z < 0)
            {
                this.dz = this.vgridsize / (0 - this.line.paraEqua.Z);
                this.tz = ingrid.Z / (0 - this.line.paraEqua.Z);
            }
        }
Пример #11
0
        /// <summary>
        /// 构造函数,参数为大地坐标
        /// </summary>
        /// <param name="start">大地坐标</param>
        /// <param name="dir">方向</param>
        public DDA3D(Point start, Vector3D dir)
        {
            Point tstart = start.clone();

            this.isCalc = this.Init();
            if (!this.isCalc)
            {
                return;
            }
            GridHelper.getInstance().getMaxAccGridXY(ref this.maxgxid, ref this.maxgyid);
            GridHelper.getInstance().getMinAccGridXY(ref this.mingxid, ref this.mingyid);

            this.isCalc = GridHelper.getInstance().PointXYZToAccGrid(tstart, ref this.cur);
            if (!this.isCalc)
            {
                return;
            }

            this.line.setLine(tstart, dir);

            this.stepx = (this.line.paraEqua.X < 0 ? -1 : 1);
            this.stepy = (this.line.paraEqua.Y < 0 ? -1 : 1);
            this.stepz = (this.line.paraEqua.Z < 0 ? -1 : 1);

            Point ingrid = new Point();

            this.isCalc = GridHelper.getInstance().PointXYZInAccGrid(tstart, ref ingrid);
            if (!this.isCalc)
            {
                return;
            }

            //double.MaxValue / 10.0 防止计算时溢出
            if (Math.Round(this.line.paraEqua.X, 3) == 0)
            {
                this.tx = this.dx = maxlength;
            }
            else if (this.line.paraEqua.X > 0)
            {
                this.dx = this.gridlength / this.line.paraEqua.X;
                this.tx = (this.gridlength - ingrid.X) / this.line.paraEqua.X;
            }
            else
            {
                this.dx = this.gridlength / (0 - this.line.paraEqua.X);
                this.tx = ingrid.X / (0 - this.line.paraEqua.X);
            }
            if (Math.Round(this.line.paraEqua.Y, 3) == 0)
            {
                this.ty = this.dy = maxlength;
            }
            else if (this.line.paraEqua.Y > 0)
            {
                this.dy = this.gridlength / this.line.paraEqua.Y;
                this.ty = (this.gridlength - ingrid.Y) / this.line.paraEqua.Y;
            }
            else
            {
                this.dy = this.gridlength / (0 - this.line.paraEqua.Y);
                this.ty = ingrid.Y / (0 - this.line.paraEqua.Y);
            }
            if (Math.Round(this.line.paraEqua.Z, 3) == 0)
            {
                this.tz = this.dz = maxlength;//因为tz很大,所以dz随便定义
            }
            else
            {
                if (this.cur.gzid == 3 && this.line.paraEqua.Z > 0)
                {
                    this.tz = this.dz = maxlength;
                }
                else if (this.line.paraEqua.Z > 0)
                {
                    this.dz = this.vgridsize / this.line.paraEqua.Z;
                    this.tz = (this.vgridsize - ingrid.Z) / this.line.paraEqua.Z;
                }
                else if (this.line.paraEqua.Z < 0)
                {
                    this.dz = this.vgridsize / (0 - this.line.paraEqua.Z);
                    this.tz = ingrid.Z / (0 - this.line.paraEqua.Z);
                }
            }
        }