private unsafe void TileOperationAction(IPointDataTileChunk chunk)
        {
            //ushort gridSize = (ushort)Math.Sqrt(chunk.Tile.PointCount);

            //var grid = new Grid<List<int>>(gridSize, gridSize, null, true);

            //UQuantizedExtent3D quantizedExtent = chunk.Tile.QuantizedExtent;

            //double cellSizeX = (double)quantizedExtent.RangeX / gridSize;
            //double cellSizeY = (double)quantizedExtent.RangeY / gridSize;

            //int i = 0;
            //byte* pb = chunk.PointDataPtr;
            //while (pb < chunk.PointDataEndPtr)
            //{
            //    var p = (SQuantizedPoint3D*)pb;

            //    int pixelX = (int)(((*p).X - quantizedExtent.MinX) / cellSizeX);
            //    int pixelY = (int)(((*p).Y - quantizedExtent.MinY) / cellSizeY);

            //    if (grid.Data[pixelX, pixelY] == null)
            //        grid.Data[pixelX, pixelY] = new List<int>();

            //    grid.Data[pixelX, pixelY].Add(i);

            //    pb += chunk.PointSizeBytes;
            //    ++i;
            //}

            //uint maxRegionCount = 0;

            //int windowSize = 10;
            //int windowRadius = windowSize / 2;
            //for (int x = 0; x < grid.SizeX; x++)
            //{
            //    for (int y = 0; y < grid.SizeY; y++)
            //    {
            //        var pointIndices = grid.Data[x, y];
            //        if (pointIndices != null)
            //        {
            //            uint regionCount = 0;
            //            for (int x1 = x - windowRadius; x1 < x + windowRadius; x1++)
            //            {
            //                for (int y1 = y - windowRadius; y1 < y + windowRadius; y1++)
            //                {
            //                    var pointIndices1 = grid.Data[x, y];
            //                    if(pointIndices1 != null)
            //                        regionCount += (uint)pointIndices1.Count;
            //                }
            //            }

            //            maxRegionCount = Math.Max(maxRegionCount, regionCount);

            //            for (int index = 0; index < pointIndices.Count; index++)
            //            {
            //                UQuantizedPoint3D* p = (UQuantizedPoint3D*)(chunk.PointDataPtr + chunk.PointSizeBytes * pointIndices[index]);
            //                (*p).Z = regionCount;
            //            }
            //        }
            //    }
            //}

            //pb = chunk.PointDataPtr;
            //while (pb < chunk.PointDataEndPtr)
            //{
            //    UQuantizedPoint3D* p = (UQuantizedPoint3D*)pb;

            //    if ((*p).Z > maxRegionCount)
            //        (*p).Z = maxRegionCount;

            //    (*p).Z = (*p).Z * quantizedExtent.RangeZ / maxRegionCount + quantizedExtent.MinZ;

            //    pb += chunk.PointSizeBytes;
            //}
        }
        private unsafe void TileOperationAction(IPointDataTileChunk chunk)
        {
            //ushort gridSize = (ushort)Math.Sqrt(chunk.Tile.PointCount);

            //var grid = new Grid<List<int>>(gridSize, gridSize, null, true);

            //UQuantizedExtent3D quantizedExtent = chunk.Tile.QuantizedExtent;

            //double cellSizeX = (double)quantizedExtent.RangeX / gridSize;
            //double cellSizeY = (double)quantizedExtent.RangeY / gridSize;

            //int i = 0;
            //byte* pb = chunk.PointDataPtr;
            //while (pb < chunk.PointDataEndPtr)
            //{
            //    var p = (SQuantizedPoint3D*)pb;

            //    int pixelX = (int)(((*p).X - quantizedExtent.MinX) / cellSizeX);
            //    int pixelY = (int)(((*p).Y - quantizedExtent.MinY) / cellSizeY);

            //    if (grid.Data[pixelX, pixelY] == null)
            //        grid.Data[pixelX, pixelY] = new List<int>();

            //    grid.Data[pixelX, pixelY].Add(i);

            //    pb += chunk.PointSizeBytes;
            //    ++i;
            //}

            //uint maxRegionCount = 0;

            //int windowSize = 10;
            //int windowRadius = windowSize / 2;
            //for (int x = 0; x < grid.SizeX; x++)
            //{
            //    for (int y = 0; y < grid.SizeY; y++)
            //    {
            //        var pointIndices = grid.Data[x, y];
            //        if (pointIndices != null)
            //        {
            //            uint regionCount = 0;
            //            for (int x1 = x - windowRadius; x1 < x + windowRadius; x1++)
            //            {
            //                for (int y1 = y - windowRadius; y1 < y + windowRadius; y1++)
            //                {
            //                    var pointIndices1 = grid.Data[x, y];
            //                    if(pointIndices1 != null)
            //                        regionCount += (uint)pointIndices1.Count;
            //                }
            //            }

            //            maxRegionCount = Math.Max(maxRegionCount, regionCount);

            //            for (int index = 0; index < pointIndices.Count; index++)
            //            {
            //                UQuantizedPoint3D* p = (UQuantizedPoint3D*)(chunk.PointDataPtr + chunk.PointSizeBytes * pointIndices[index]);
            //                (*p).Z = regionCount;
            //            }
            //        }
            //    }
            //}

            //pb = chunk.PointDataPtr;
            //while (pb < chunk.PointDataEndPtr)
            //{
            //    UQuantizedPoint3D* p = (UQuantizedPoint3D*)pb;

            //    if ((*p).Z > maxRegionCount)
            //        (*p).Z = maxRegionCount;

            //    (*p).Z = (*p).Z * quantizedExtent.RangeZ / maxRegionCount + quantizedExtent.MinZ;

            //    pb += chunk.PointSizeBytes;
            //}
        }