public static Boundary GetBoundaryExtended(JsonGetMarkersReceive input)
        {
            var deltas = GetDelta(GmcSettings.Get.Gridx, GmcSettings.Get.Gridy, input.Zoomlevel);
            var deltaX = deltas[0];
            var deltaY = deltas[1];

            // Grid with extended outer grid-area non-visible
            var a  = MathTool.FloorLatLon(input.Viewport.Minx, deltaX) - deltaX * GmcSettings.Get.OuterGridExtend;
            var b  = MathTool.FloorLatLon(input.Viewport.Miny, deltaY) - deltaY * GmcSettings.Get.OuterGridExtend;
            var a2 = MathTool.FloorLatLon(input.Viewport.Maxx, deltaX) + deltaX * (1 + GmcSettings.Get.OuterGridExtend);
            var b2 = MathTool.FloorLatLon(input.Viewport.Maxy, deltaY) + deltaY * (1 + GmcSettings.Get.OuterGridExtend);

            // Latitude is special with Google Maps, they don't wrap around, then do constrain
            b  = MathTool.ConstrainLatitude(b);
            b2 = MathTool.ConstrainLatitude(b2);

            var grid = new Boundary {
                Minx = a, Miny = b, Maxx = a2, Maxy = b2
            };

            grid.Normalize();
            return(grid);
        }
        public static Boundary GetBoundaryExtended(MarkersInput input)
        {
            var deltas = GetDelta(GmcConfiguration.Get.GridX, GmcConfiguration.Get.GridY, input.Zoomlevel);
            var deltaX = deltas[0];
            var deltaY = deltas[1];

            // Grid with extended outer grid-area non-visible
            var a  = MathTool.FloorLatLon(input.Viewport.MinX, deltaX) - deltaX * GmcConfiguration.Get.OuterGridExtend;
            var b  = MathTool.FloorLatLon(input.Viewport.MinY, deltaY) - deltaY * GmcConfiguration.Get.OuterGridExtend;
            var a2 = MathTool.FloorLatLon(input.Viewport.MaxX, deltaX) + deltaX * (1 + GmcConfiguration.Get.OuterGridExtend);
            var b2 = MathTool.FloorLatLon(input.Viewport.MaxY, deltaY) + deltaY * (1 + GmcConfiguration.Get.OuterGridExtend);

            // Latitude is special with Google Maps, they don't wrap around, then do constrain
            b  = MathTool.ConstrainLatitude(b);
            b2 = MathTool.ConstrainLatitude(b2);

            var grid = new Boundary {
                MinX = a, MinY = b, MaxX = a2, MaxY = b2
            };

            grid.Normalize();
            return(grid);
        }
        /// <summary>
        /// For debugging purpose
        /// Display the red grid lines on the map to show how the points are clustered
        /// </summary>
        /// <returns></returns>
        public IList <Line> GetPolyLines()
        {
            if (!GmcSettings.Get.DoShowGridLinesInGoogleMap)
            {
                return(null);                                                         // server disabled it
            }
            if (!_jsonReceive.IsDebugLinesEnabled)
            {
                return(null);                                               // client disabled it
            }
            // Make the red lines data to be drawn in Google map

            var temp = new List <Rectangle>();

            const int borderLinesAdding = 1;
            var       linesStepsX       = (int)(Math.Round(Grid.AbsX / DeltaX) + borderLinesAdding);
            var       linesStepsY       = (int)(Math.Round(Grid.AbsY / DeltaY) + borderLinesAdding);

            var          b           = new Boundary(Grid);
            const double restrictLat = 5.5;                           // heuristic value, Google maps related

            b.Miny = MathTool.ConstrainLatitude(b.Miny, restrictLat); // Make sure it is visible on screen, restrict by some value
            b.Maxy = MathTool.ConstrainLatitude(b.Maxy, restrictLat);

            // Vertical lines
            for (var i = 0; i < linesStepsX; i++)
            {
                var xx = b.Minx + i * DeltaX;

                // Draw region
                if (_jsonReceive.Zoomlevel > 3)                 // heuristic value, Google maps related
                {
                    temp.Add(new Rectangle {
                        Minx = xx, Miny = b.Miny, Maxx = xx, Maxy = b.Maxy
                    });
                }
                // World wrap issue when same latlon area visible multiple times
                // Make sure line is drawn from left to right on screen
                else
                {
                    temp.Add(new Rectangle {
                        Minx = xx, Miny = LatLonInfo.MinLatValue + restrictLat, Maxx = xx, Maxy = 0
                    });
                    temp.Add(new Rectangle {
                        Minx = xx, Miny = 0, Maxx = xx, Maxy = LatLonInfo.MaxLatValue - restrictLat
                    });
                }
            }

            // Horizontal lines
            for (var i = 0; i < linesStepsY; i++)
            {
                var yy = b.Miny + i * DeltaY;

                // Draw region
                if (_jsonReceive.Zoomlevel > 3)                  // heuristic value
                {
                    // Don't draw lines outsize the world
                    if (MathTool.IsLowerThanLatMin(yy) || MathTool.IsGreaterThanLatMax(yy))
                    {
                        continue;
                    }

                    temp.Add(new Rectangle {
                        Minx = b.Minx, Miny = yy, Maxx = b.Maxx, Maxy = yy
                    });
                }
                // World wrap issue when same latlon area visible multiple times
                // Make sure line is drawn from left to right on screen
                else
                {
                    temp.Add(new Rectangle {
                        Minx = LatLonInfo.MinLonValue, Miny = yy, Maxx = 0, Maxy = yy
                    });
                    temp.Add(new Rectangle {
                        Minx = 0, Miny = yy, Maxx = LatLonInfo.MaxLonValue, Maxy = yy
                    });
                }
            }

            var lines = new List <Line>();

            // Normalize the lines and add as string
            foreach (var line in temp)
            {
                var x  = (line.Minx).NormalizeLongitude().DoubleToString();
                var x2 = (line.Maxx).NormalizeLongitude().DoubleToString();
                var y  = (line.Miny).NormalizeLatitude().DoubleToString();
                var y2 = (line.Maxy).NormalizeLatitude().DoubleToString();
                lines.Add(new Line {
                    X = x, Y = y, X2 = x2, Y2 = y2
                });
            }
            return(lines);
        }