示例#1
0
        public GridIndexCell(GridIndexCell a, GridIndexCell b)
        {
            m_chunks = new HashSet <int>();

            if (a != null)
            {
                foreach (var c in a.m_chunks)
                {
                    m_chunks.Add(c);
                }
            }

            if (b != null)
            {
                foreach (var c in b.m_chunks)
                {
                    m_chunks.Add(c);
                }
            }
        }
示例#2
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());
        }