コード例 #1
0
        /// <summary>
        /// 构建当前缩放层级的瓦片
        /// </summary>
        /// <param name="bound"></param>
        /// <param name="zoom"></param>
        void Build(GBound bound, int zoom)
        {
            int _tileSize = Projection.TileSize;
            //构建裁剪边界的矩形,用于整体裁剪
            IGeometry _boundGeometry = bound.ToInsertPolygon();

            //瓦片多尺度缓存
            if (TileDictionary.ContainsKey(zoom))
            {
                TileDictionary[zoom].Clear();
            }
            else
            {
                TileDictionary[zoom] = new List <GTileElement>();
            }
            //1.获取坐上右下坐标
            Coordinate p0 = bound.Min;
            Coordinate p1 = bound.Max;
            //2.分尺度计算格网位置
            //2.1 转换成尺度下的pixel
            Coordinate min = Projection.LatlngToPoint(p0, zoom);
            Coordinate max = Projection.LatlngToPoint(p1, zoom);
            //2.2 计算pixel下边界范围
            GBound pixelBound = new GBound(new List <Coordinate>()
            {
                min, max
            });
            //2.3 通过pixelbound计算range
            GBound range = new GBound(new List <Coordinate>()
            {
                new Coordinate((int)Math.Floor(pixelBound.Min.X / _tileSize), (int)Math.Floor(pixelBound.Min.Y / _tileSize)),
                new Coordinate((int)Math.Ceiling(pixelBound.Max.X / _tileSize) - 1, (int)Math.Ceiling(pixelBound.Max.Y / _tileSize) - 1),
            });

            //2.3统计区域内瓦片的编号,边界经纬度等信息
            for (int j = Convert.ToInt32(range.Min.Y); j <= Convert.ToInt32(range.Max.Y); j++)
            {
                for (int i = Convert.ToInt32(range.Min.X); i <= Convert.ToInt32(range.Max.X); i++)
                {
                    //反算每块瓦片的边界经纬度
                    List <Coordinate> coordinates = new List <Coordinate>();
                    coordinates.Add(Projection.PointToLatLng(new Coordinate(i * 256, j * 256), zoom));
                    coordinates.Add(Projection.PointToLatLng(new Coordinate(i * 256 + 256, j * 256 + 256), zoom));
                    //
                    GTileElement tile = new GTileElement()
                    {
                        X     = i,
                        Y     = j,
                        Z     = zoom,
                        Bound = new GBound(coordinates)
                    };
                    TileDictionary[zoom].Add(tile);
                }
            }
        }
コード例 #2
0
 /// <summary>
 /// 构造函数
 /// example var layer = new WebMercatorGridLayer()
 /// </summary>
 /// <param name="bound"></param>
 public VectorPyramid(GBound bound = null)
 {
     if (bound == null)
     {
         bound = new GBound(new List <Coordinate>()
         {
             new Coordinate(-180, 90), new Coordinate(180, -90)
         });
     }
     for (int i = 0; i <= 19; i++)
     {
         Build(bound, i);
     }
 }
コード例 #3
0
ファイル: CohenSutherland.cs プロジェクト: lulzzz/kiwi.server
        /// <summary>
        /// 给当前坐标编码
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="bound"></param>
        /// <returns></returns>
        private static byte Encode(double x, double y, GBound bound)
        {
            double xl = bound.Left, xr = bound.Right, yt = bound.Top, yb = bound.Bottom;
            byte   c = 0;

            if (x < xl)
            {
                c |= LEFT;
            }
            if (x > xr)
            {
                c |= RIGHT;
            }
            if (y < yb)
            {
                c |= BOTTOM;
            }
            if (y > yt)
            {
                c |= TOP;
            }
            return(c);
        }
コード例 #4
0
ファイル: CohenSutherland.cs プロジェクト: lulzzz/kiwi.server
        /// <summary>
        /// 裁剪线段
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="bound"></param>
        /// <returns></returns>
        private static List <Coordinate> ClipLine(Coordinate start, Coordinate end, GBound bound)
        {
            double xl = bound.Left,
                   xr = bound.Right,
                   yt = bound.Top,
                   yb = bound.Bottom;
            //
            List <Coordinate> coords = new List <Coordinate>();
            double            x1 = start.X, y1 = start.Y, x2 = end.X, y2 = end.Y;
            byte   code1 = Encode(x1, y1, bound);
            byte   code2 = Encode(x2, y2, bound);
            byte   code;
            double x = 0, y = 0;

            while (code1 != 0 || code2 != 0)
            {
                //1.线在窗口外,返回一个空数组
                if ((code1 & code2) != 0)
                {
                    return(coords);
                }
                code = code1;
                //找窗口外的点
                if (code1 == 0)
                {
                    code = code2;
                }
                //点在左边
                if ((LEFT & code) != 0)
                {
                    x = xl;
                    y = y1 + (y2 - y1) * (xl - x1) / (x2 - x1);
                }
                //点在右边
                else if ((RIGHT & code) != 0)
                {
                    x = xr;
                    y = y1 + (y2 - y1) * (xr - x1) / (x2 - x1);
                }
                //点在下面
                else if ((BOTTOM & code) != 0)
                {
                    y = yb;
                    x = x1 + (x2 - x1) * (yb - y1) / (y2 - y1);
                }
                else if ((TOP & code) != 0)
                {
                    y = yt;
                    x = x1 + (x2 - x1) * (yt - y1) / (y2 - y1);
                }
                //
                if (code == code1)
                {
                    x1    = x;
                    y1    = y;
                    code1 = Encode(x, y, bound);
                }
                else
                {
                    x2    = x;
                    y2    = y;
                    code2 = Encode(x, y, bound);
                }
            }
            //
            coords.Add(new Coordinate(x1, y1));
            coords.Add(new Coordinate(x2, y2));
            return(coords);
        }
コード例 #5
0
ファイル: CohenSutherland.cs プロジェクト: lulzzz/kiwi.server
        /// <summary>
        /// 裁剪线
        /// </summary>
        /// <param name="subjectPolyline"></param>
        /// <param name="bound"></param>
        /// <returns></returns>
        public static List <Coordinate> GetIntersectedPolyline(Coordinate[] subjectPolyline, GBound bound)
        {
            List <Coordinate> clipLines = new List <Coordinate>();

            for (int i = 0; i < subjectPolyline.Length - 1; i++)
            {
                Coordinate        p0     = subjectPolyline[i];
                Coordinate        p1     = subjectPolyline[i + 1];
                List <Coordinate> cliped = ClipLine(p0, p1, bound);
                clipLines.AddRange(cliped);
            }
            return(clipLines);
        }
コード例 #6
0
        public static List <Coordinate> GetIntersectedPolygon(Coordinate[] subjectPoly, GBound bound)
        {
            Coordinate[] clipPoly = bound.ToClipPolygon();
            if (subjectPoly.Length < 3)
            {
                throw new ArgumentException(string.Format("The polygons passed in must have at least 3 points: subject={0}", subjectPoly.Length.ToString()));
            }
            List <Coordinate> outputList = subjectPoly.ToList();

            //	Make sure it's clockwise
            if (!IsClockwise(subjectPoly))
            {
                outputList.Reverse();
            }
            //	Walk around the clip polygon clockwise
            foreach (Edge clipEdge in IterateEdgesClockwise(clipPoly))
            {
                List <Coordinate> inputList = outputList.ToList();               //	clone it
                outputList.Clear();

                if (inputList.Count == 0)
                {
                    //	Sometimes when the polygons don't intersect, this list goes to zero.  Jump out to avoid an index out of range exception
                    break;
                }

                Coordinate S = inputList[inputList.Count - 1];

                foreach (Coordinate E in inputList)
                {
                    if (IsInside(clipEdge, E))
                    {
                        if (!IsInside(clipEdge, S))
                        {
                            Coordinate point = GetIntersect(S, E, clipEdge.From, clipEdge.To);
                            outputList.Add(point);
                        }

                        outputList.Add(E);
                    }
                    else if (IsInside(clipEdge, S))
                    {
                        Coordinate point = GetIntersect(S, E, clipEdge.From, clipEdge.To);
                        outputList.Add(point);
                    }

                    S = E;
                }
            }
            //	Exit Function
            return(outputList);
        }