示例#1
0
        public unsafe IPointDataChunk Process(IPointDataChunk chunk)
        {
            if (chunk.PointCount > m_maxPointCountPerChunk)
            {
                m_maxPointCountPerChunk = chunk.PointCount;
            }

            // get the tile indices for this chunk
            var tileIndices = new HashSet <int>();
            var lastIndex   = -1;

            // JUST TESTING TO SEE IF I LIKE THIS WAY BETTER (slightly slower?)
            //var iterator = new SQuantizedPoint3DIterator(chunk);
            //while (iterator.IsValid)
            //{
            //    var p = iterator.Next();
            //    var y = (ushort)(((*p).Y - minY) * tilesOverRangeY);
            //    var x = (ushort)(((*p).X - minX) * tilesOverRangeX);

            //    ++m_grid.Data[y, x];

            //    // indexing
            //    int tileIndex = PointCloudTileCoord.GetIndex(y, x);
            //    if (tileIndex != lastIndex)
            //    {
            //        tileIndices.Add(tileIndex);
            //        lastIndex = tileIndex;
            //    }
            //}

            // JUST TESTING TO SEE IF I LIKE THIS WAY BETTER (slightly slower?)
            foreach (var pp in chunk.GetSQuantizedPoint3DEnumerator())
            {
                //var p = (LASPointFormat1*)pp.GetPointer();
                var p = pp.GetPointer();
                var y = (((*p).Y - m_quantizedExtent.MinY) / m_grid.CellSizeY);
                var x = (((*p).X - m_quantizedExtent.MinX) / m_grid.CellSizeX);

                ++m_grid.Data[y, x];

                // indexing
                int tileIndex = PointCloudTileCoord.GetIndex(y, x);
                if (tileIndex != lastIndex)
                {
                    tileIndices.Add(tileIndex);
                    lastIndex = tileIndex;
                }
            }

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

            //    var y = (ushort)(((*p).Y - minY) * tilesOverRangeY);
            //    var x = (ushort)(((*p).X - minX) * tilesOverRangeX);

            //    ++m_grid.Data[y, x];

            //    // indexing
            //    int tileIndex = PointCloudTileCoord.GetIndex(y, x);
            //    if (tileIndex != lastIndex)
            //    {
            //        tileIndices.Add(tileIndex);
            //        lastIndex = tileIndex;
            //    }

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

            m_chunkTiles.Add(tileIndices.ToArray());

            return(chunk);
        }
示例#2
0
        private PointCloudTile GetTileInternal(int row, int col)
        {
            var index = -1;

            return(m_tileIndex.TryGetValue(PointCloudTileCoord.GetIndex(row, col), out index) ? m_tiles[index] : null);
        }
示例#3
0
        public List <PointCloudBinarySourceEnumeratorSparseGridRegion> GetGridIndex(PointCloudTileDensity density, int maxSegmentLength)
        {
            var maxSegmentPointCount = (maxSegmentLength / m_source.PointSizeBytes);

            // update index cells
            var indexGrid = (SQuantizedExtentGrid <GridIndexCell>)m_grid.Copy <GridIndexCell>();

            for (var i = 0; i < m_chunkTiles.Count; i++)
            {
                foreach (var tileIndex in m_chunkTiles[i])
                {
                    var coord     = new PointCloudTileCoord(tileIndex);
                    var indexCell = indexGrid.Data[coord.Row, coord.Col];
                    if (indexCell == null)
                    {
                        indexCell = new GridIndexCell();
                        indexGrid.Data[coord.Row, coord.Col] = indexCell;
                    }
                    indexCell.Add(i);
                }
            }
            indexGrid.CorrectCountOverflow();

            var actualGrid = density.CreateTileCountsForInitialization(m_source);

            var regionSourcesBySegment = new List <List <Range> >();
            var tilesPerSegment        = new List <GridRange>();
            var pointDataBytes         = m_source.PointSizeBytes * m_source.Count;

            var tileOrder      = PointCloudTileSet.GetTileOrdering(actualGrid.SizeY, actualGrid.SizeX).ToArray();
            var tileOrderIndex = 0;

            while (tileOrderIndex < tileOrder.Length)
            {
                var segmentTilesFromEstimation = new HashSet <int>();
                var segmentChunks = new HashSet <int>();

                var startTile      = tileOrder[tileOrderIndex];
                var startTileIndex = new GridCoord(actualGrid.Def, startTile.Row, startTile.Col);

                var segmentProbableValidTileCount = 0;

                var segmentPointCount = 0;

                while (tileOrderIndex < tileOrder.Length)
                {
                    var tile = tileOrder[tileOrderIndex];

                    // unfortunately, I cannot check the actual counts, because they have not been measured
                    // instead, I can count the estimated area, and undershoot

                    // get unique tiles/chunks

                    var uniqueEstimatedCoords = indexGrid
                                                .GetCellCoordsInScaledRange(tile.Col, tile.Row, actualGrid)
                                                .Where(c => !segmentTilesFromEstimation.Contains(c.Index))
                                                .ToList();

                    // count probable valid tiles for low-res estimation
                    if (uniqueEstimatedCoords.Count > 0)
                    {
                        var uniquePointCount = uniqueEstimatedCoords.Sum(c => m_grid.Data[c.Row, c.Col]);

                        if (segmentPointCount + uniquePointCount > maxSegmentPointCount)
                        {
                            break;
                        }

                        var uniqueChunks = uniqueEstimatedCoords
                                           .Select(c => indexGrid.Data[c.Row, c.Col])
                                           .SelectMany(c => c.Chunks)
                                           .ToHashSet(segmentChunks);

                        // no longer limiting the chunks per segment to fit buffer.
                        // this means that the full chunk data will almost certainly
                        // *not* fit in the segment buffer, but the filtered data will.

                        // merge tiles/chunks
                        foreach (var coord in uniqueEstimatedCoords)
                        {
                            segmentTilesFromEstimation.Add(coord.Index);
                        }

                        foreach (var index in uniqueChunks)
                        {
                            segmentChunks.Add(index);
                        }

                        segmentPointCount += uniquePointCount;

                        ++segmentProbableValidTileCount;
                    }

                    ++tileOrderIndex;
                }

                if (segmentChunks.Count > 0)
                {
                    var endTile      = tileOrder[tileOrderIndex - 1];
                    var endTileIndex = new GridCoord(actualGrid.Def, endTile.Row, endTile.Col);

                    // group by sequential regions
                    var sortedCellList = segmentChunks.ToArray();
                    Array.Sort(sortedCellList);
                    var regions            = new List <Range>();
                    var sequenceStartIndex = 0;
                    while (sequenceStartIndex < sortedCellList.Length)
                    {
                        // find incremental sequence
                        int i = sequenceStartIndex;
                        ++i;
                        while (i < sortedCellList.Length && (sortedCellList[i] == sortedCellList[i - 1] + 1))
                        {
                            ++i;
                        }
                        regions.Add(new Range(sortedCellList[sequenceStartIndex], i - sequenceStartIndex));
                        sequenceStartIndex = i;
                    }

                    regionSourcesBySegment.Add(regions);
                    tilesPerSegment.Add(new GridRange(startTileIndex, endTileIndex, segmentProbableValidTileCount));
                }
            }

            var chunkRangeSumForAllSegments = regionSourcesBySegment.Sum(r => r.Sum(r2 => r2.Count));

            Context.WriteLine("chunkRangeSumForAllSegments: {0}", chunkRangeSumForAllSegments);
            Context.WriteLine("  ratio: {0}", (double)chunkRangeSumForAllSegments * BufferManager.BUFFER_SIZE_BYTES / pointDataBytes);

            return(regionSourcesBySegment.Select((t, i) => new PointCloudBinarySourceEnumeratorSparseGridRegion(t, tilesPerSegment[i], m_maxPointCountPerChunk)).ToList());
        }
示例#4
0
 private PointCloudTile GetTile(PointCloudTileCoord tile)
 {
     return(GetTileInternal(tile.Row, tile.Col));
 }