/**
         * Checks that "covering" completely covers the given region. If "check_tight"
         * is true, also checks that it does not contain any cells that do not
         * intersect the given region. ("id" is only used internally.)
         */

        protected void checkCovering(IS2Region region, S2CellUnion covering, bool checkTight, S2CellId id)
        {
            if (!id.IsValid)
            {
                for (var face = 0; face < 6; ++face)
                {
                    checkCovering(region, covering, checkTight, S2CellId.FromFacePosLevel(face, 0, 0));
                }
                return;
            }

            if (!region.MayIntersect(new S2Cell(id)))
            {
                // If region does not intersect id, then neither should the covering.
                if (checkTight)
                {
                    Assert.True(!covering.Intersects(id));
                }
            }
            else if (!covering.Contains(id))
            {
                // The region may intersect id, but we can't assert that the covering
                // intersects id because we may discover that the region does not actually
                // intersect upon further subdivision. (MayIntersect is not exact.)
                Assert.True(!region.Contains(new S2Cell(id)));
                var result = !id.IsLeaf;
                Assert.True(result);
                var end = id.ChildEnd;
                for (var child = id.ChildBegin; !child.Equals(end); child = child.Next)
                {
                    checkCovering(region, covering, checkTight, child);
                }
            }
        }
예제 #2
0
        public void Test_S2CellUnion_Normalize()
        {
            // Try a bunch of random test cases, and keep track of average
            // statistics for normalization (to see if they agree with the
            // analysis above).
            double    in_sum = 0, out_sum = 0;
            const int kIters = 2000;

            for (int i = 0; i < kIters; ++i)
            {
                var input    = new List <S2CellId>();
                var expected = new List <S2CellId>();
                AddCells(S2CellId.None, false, input, expected);
                in_sum  += input.Count;
                out_sum += expected.Count;
                var cellunion = new S2CellUnion(input);
                Assert.Equal(expected.Count, cellunion.Size());
                for (var j = 0; j < expected.Count; ++j)
                {
                    Assert.Equal(expected[j], cellunion.CellId(j));
                }

                // Test GetCapBound().
                var cap = cellunion.GetCapBound();
                foreach (var id in cellunion)
                {
                    Assert.True(cap.Contains(new S2Cell(id)));
                }

                // Test Contains(S2CellId) and Intersects(S2CellId).
                foreach (var input_id in input)
                {
                    Assert.True(cellunion.Contains(input_id));
                    Assert.True(cellunion.Contains(input_id.ToPoint()));
                    Assert.True(cellunion.Intersects(input_id));
                    if (!input_id.IsFace())
                    {
                        Assert.True(cellunion.Intersects(input_id.Parent()));
                        if (input_id.Level() > 1)
                        {
                            Assert.True(cellunion.Intersects(input_id.Parent().Parent()));
                            Assert.True(cellunion.Intersects(input_id.Parent(0)));
                        }
                    }
                    if (!input_id.IsLeaf())
                    {
                        Assert.True(cellunion.Contains(input_id.ChildBegin()));
                        Assert.True(cellunion.Intersects(input_id.ChildBegin()));
                        Assert.True(cellunion.Contains(input_id.ChildEnd().Prev()));
                        Assert.True(cellunion.Intersects(input_id.ChildEnd().Prev()));
                        Assert.True(cellunion.Contains(input_id.ChildBegin(S2.kMaxCellLevel)));
                        Assert.True(cellunion.Intersects(input_id.ChildBegin(S2.kMaxCellLevel)));
                    }
                }
                foreach (var expected_id in expected)
                {
                    if (!expected_id.IsFace())
                    {
                        Assert.True(!cellunion.Contains(expected_id.Parent()));
                        Assert.True(!cellunion.Contains(expected_id.Parent(0)));
                    }
                }

                // Test Contains(S2CellUnion), Intersects(S2CellUnion), Union(),
                // Intersection(), and Difference().
                var x       = new List <S2CellId>();
                var y       = new List <S2CellId>();
                var x_or_y  = new List <S2CellId>();
                var x_and_y = new List <S2CellId>();
                foreach (var input_id in input)
                {
                    var in_x = rnd.OneIn(2);
                    var in_y = rnd.OneIn(2);
                    if (in_x)
                    {
                        x.Add(input_id);
                    }
                    if (in_y)
                    {
                        y.Add(input_id);
                    }
                    if (in_x || in_y)
                    {
                        x_or_y.Add(input_id);
                    }
                }
                var xcells          = new S2CellUnion(x);
                var ycells          = new S2CellUnion(y);
                var x_or_y_expected = new S2CellUnion(x_or_y);
                var x_or_y_cells    = xcells.Union(ycells);
                Assert.True(x_or_y_cells == x_or_y_expected);

                // Compute the intersection of "x" with each cell of "y",
                // check that this intersection is correct, and append the
                // results to x_and_y_expected.
                foreach (var yid in ycells)
                {
                    var ucells = xcells.Intersection(yid);
                    foreach (var xid in xcells)
                    {
                        if (xid.Contains(yid))
                        {
                            Assert.True(ucells.Size() == 1 && ucells.CellId(0) == yid);
                        }
                        else if (yid.Contains(xid))
                        {
                            Assert.True(ucells.Contains(xid));
                        }
                    }
                    foreach (var uid in ucells)
                    {
                        Assert.True(xcells.Contains(uid));
                        Assert.True(yid.Contains(uid));
                    }
                    x_and_y.AddRange(ucells);
                }
                var x_and_y_expected = new S2CellUnion(x_and_y);
                var x_and_y_cells    = xcells.Intersection(ycells);
                Assert.True(x_and_y_cells == x_and_y_expected);

                var x_minus_y_cells = xcells.Difference(ycells);
                var y_minus_x_cells = ycells.Difference(xcells);
                Assert.True(xcells.Contains(x_minus_y_cells));
                Assert.True(!x_minus_y_cells.Intersects(ycells));
                Assert.True(ycells.Contains(y_minus_x_cells));
                Assert.True(!y_minus_x_cells.Intersects(xcells));
                Assert.True(!x_minus_y_cells.Intersects(y_minus_x_cells));

                var diff_intersection_union = x_minus_y_cells.Union(y_minus_x_cells).Union(x_and_y_cells);
                Assert.True(diff_intersection_union == x_or_y_cells);

                var test  = new List <S2CellId>();
                var dummy = new List <S2CellId>();
                AddCells(S2CellId.None, false, test, dummy);
                foreach (var test_id in test)
                {
                    var contains   = false;
                    var intersects = false;
                    foreach (var expected_id in expected)
                    {
                        if (expected_id.Contains(test_id))
                        {
                            contains = true;
                        }
                        if (expected_id.Intersects(test_id))
                        {
                            intersects = true;
                        }
                    }
                    Assert.Equal(contains, cellunion.Contains(test_id));
                    Assert.Equal(intersects, cellunion.Intersects(test_id));
                }
            }
            _logger.WriteLine($"avg in {in_sum / kIters:2f}, avg out {out_sum / kIters:2f}");
        }
예제 #3
0
    private void TestRandomCaps(S2RegionTermIndexer.Options options, QueryType query_type)
    {
        // This function creates an index consisting either of points (if
        // options.index_contains_points_only() is true) or S2Caps of random size.
        // It then executes queries consisting of points (if query_type == POINT)
        // or S2Caps of random size (if query_type == CAP).
        var indexer = new S2RegionTermIndexer(options);
        var coverer = new S2RegionCoverer(options);
        var caps = new List <S2Cap>();
        var coverings = new List <S2CellUnion>();
        var index = new Dictionary <string, List <int> >();
        int index_terms = 0, query_terms = 0;

        for (int i = 0; i < iters; ++i)
        {
            // Choose the region to be indexed: either a single point or a cap
            // of random size (up to a full sphere).
            S2Cap         cap;
            List <string> terms;
            if (options.IndexContainsPointsOnly)
            {
                cap   = S2Cap.FromPoint(S2Testing.RandomPoint());
                terms = indexer.GetIndexTerms(cap.Center, "");
            }
            else
            {
                cap = S2Testing.GetRandomCap(
                    0.3 * S2Cell.AverageArea(options.MaxLevel),
                    4.0 * S2Cell.AverageArea(options.MinLevel));
                terms = indexer.GetIndexTerms(cap, "");
            }
            caps.Add(cap);
            coverings.Add(coverer.GetCovering(cap));
            foreach (var term in terms)
            {
                if (!index.ContainsKey(term))
                {
                    index.Add(term, new List <int>());
                }

                index[term].Add(i);
            }
            index_terms += terms.Count;
        }
        for (int i = 0; i < iters; ++i)
        {
            // Choose the region to be queried: either a random point or a cap of
            // random size.
            S2Cap         cap;
            List <string> terms;
            if (query_type == QueryType.CAP)
            {
                cap   = S2Cap.FromPoint(S2Testing.RandomPoint());
                terms = indexer.GetQueryTerms(cap.Center, "");
            }
            else
            {
                cap = S2Testing.GetRandomCap(
                    0.3 * S2Cell.AverageArea(options.MaxLevel),
                    4.0 * S2Cell.AverageArea(options.MinLevel));
                terms = indexer.GetQueryTerms(cap, "");
            }
            // Compute the expected results of the S2Cell query by brute force.
            S2CellUnion covering = coverer.GetCovering(cap);
            var         expected = new List <int>();
            var         actual   = new List <int>();
            for (int j = 0; j < caps.Count; ++j)
            {
                if (covering.Intersects(coverings[j]))
                {
                    expected.Add(j);
                }
            }
            foreach (var term in terms)
            {
                actual.AddRange(index[term]);
            }
            Assert.Equal(expected, actual);
            query_terms += terms.Count;
        }
        _logger.WriteLine($"Index terms/doc: {((double)index_terms) / iters:2f},  Query terms/doc: {((double)query_terms) / iters:2f}");
    }
        /**
         * Checks that "covering" completely covers the given region. If "check_tight"
         * is true, also checks that it does not contain any cells that do not
         * intersect the given region. ("id" is only used internally.)
         */

        protected void checkCovering(IS2Region region, S2CellUnion covering, bool checkTight, S2CellId id)
        {
            if (!id.IsValid)
            {
                for (var face = 0; face < 6; ++face)
                {
                    checkCovering(region, covering, checkTight, S2CellId.FromFacePosLevel(face, 0, 0));
                }
                return;
            }

            if (!region.MayIntersect(new S2Cell(id)))
            {
                // If region does not intersect id, then neither should the covering.
                if (checkTight)
                {
                    Assert.True(!covering.Intersects(id));
                }
            }
            else if (!covering.Contains(id))
            {
                // The region may intersect id, but we can't assert that the covering
                // intersects id because we may discover that the region does not actually
                // intersect upon further subdivision. (MayIntersect is not exact.)
                Assert.True(!region.Contains(new S2Cell(id)));
                var result = !id.IsLeaf;
                Assert.True(result);
                var end = id.ChildEnd;
                for (var child = id.ChildBegin; !child.Equals(end); child = child.Next)
                {
                    checkCovering(region, covering, checkTight, child);
                }
            }
        }