public override IEnumerable <TileIndex> GetTilesForRegion(DataRect region, double level)
        {
            region.Intersect(rect);
            //region.Intersect(new Rect(region.XMin, minY, region.Width, maxY - minY));
            if (region.IsEmpty)
            {
                yield break;
            }

            checked
            {
                double tileWidth  = TileWidth;
                double tileHeight = TileHeight;

                int minIx = (int)Math.Floor(region.XMin / tileWidth);
                int maxIx = (int)Math.Ceiling(region.XMax / tileWidth);

                int minIy = (int)Math.Floor(region.YMin / tileHeight);
                int maxIy = (int)Math.Ceiling(region.YMax / tileHeight);

                var maxSideCount = GetSideTilesCount(Level);

                int maxIndex = maxSideCount / 2;
                if (maxIx > maxIndex)
                {
                    maxIx = maxIndex;
                }
                if (maxIy > maxIndex)
                {
                    maxIy = maxIndex;
                }
                if (minIx < -maxIndex)
                {
                    minIx = -maxIndex;
                }
                if (minIy < -maxIndex)
                {
                    minIy = -maxIndex;
                }

                if (level != 0)
                {
                    maxIx--;
                    maxIy--;
                }


                for (int ix = minIx; ix <= maxIx; ix++)
                {
                    for (int iy = minIy; iy <= maxIy; iy++)
                    {
                        yield return(new TileIndex(ix, iy, level));
                    }
                }
            }
        }
		public override DataRect Apply(DataRect previousDataRect, DataRect proposedDataRect, Viewport2D viewport)
		{
			DataRect borderRect = DataRect.Create(proposedDataRect.XMin, minSeconds, proposedDataRect.XMax, maxSeconds);
			if (proposedDataRect.IntersectsWith(borderRect))
			{
				DataRect croppedRect = DataRect.Intersect(proposedDataRect, borderRect);
				return croppedRect;
			}

			return previousDataRect;
		}
        /// <summary>
        /// Applies the specified old data rect.
        /// </summary>
        /// <param name="oldDataRect">The old data rect.</param>
        /// <param name="newDataRect">The new data rect.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        public override DataRect Apply(DataRect oldDataRect, DataRect newDataRect, Viewport2D viewport)
        {
            DataRect res = domain;

            if (domain.IsEmpty)
            {
                res = newDataRect;
            }
            else if (newDataRect.IntersectsWith(domain))
            {
                res = newDataRect;
                if (newDataRect.Size == oldDataRect.Size)
                {
                    if (res.XMin < domain.XMin)
                    {
                        res.XMin = domain.XMin;
                    }
                    if (res.YMin < domain.YMin)
                    {
                        res.YMin = domain.YMin;
                    }
                    if (res.XMax > domain.XMax)
                    {
                        res.XMin += domain.XMax - res.XMax;
                    }
                    if (res.YMax > domain.YMax)
                    {
                        res.YMin += domain.YMax - res.YMax;
                    }
                }
                else
                {
                    res = DataRect.Intersect(newDataRect, domain);
                }
            }

            return(res);
        }
        public IEnumerable <TileIndex> GetTiles(DataRect region)
        {
            region = region.Intersect(rect);
            if (region.IsEmpty)
            {
                return(Enumerable.Empty <TileIndex>());
            }

            checked
            {
                double tileWidth  = TileWidth;
                double tileHeight = TileHeight;

                int minTileX = (int)Math.Floor((region.XMin - minX) / tileWidth);
                int minTileY = (int)Math.Floor((region.YMin - minY) / tileHeight);

                double realX = minX + minTileX * tileWidth;
                double realY = minY + minTileY * tileHeight;

                int xNum = (int)Math.Ceiling((region.XMax - realX) / tileWidth);
                int yNum = (int)Math.Ceiling((region.YMax - realY) / tileHeight);

                int maxTileX = minTileX + xNum;
                int maxTileY = minTileY + yNum;

                List <TileIndex> res = new List <TileIndex>(xNum * yNum);
                for (int x = minTileX; x < maxTileX; x++)
                {
                    for (int y = minTileY; y < maxTileY; y++)
                    {
                        res.Add(new TileIndex(x, y, level));
                    }
                }

                return(res);
            }
        }