예제 #1
0
        public void NextInsideBoxTest()
        {
            Assert.Equal(27UL, ZCurve.NextInsideBox(0, 27, 102));
            Assert.Equal(74UL, ZCurve.NextInsideBox(58, 27, 102));
            Assert.Equal(74UL, ZCurve.NextInsideBox(67, 27, 102));
            Assert.Equal(96UL, ZCurve.NextInsideBox(79, 27, 102));
            Assert.Equal(74UL, ZCurve.NextInsideBox(61, 27, 102));

            // What if z is within box(qlo,qhi)? Drill down, cutting
            // off parts of the box, until a single cell remains.

            Assert.Equal(6UL, ZCurve.NextInsideBox(3, 3, 49));
            Assert.Equal(11UL, ZCurve.NextInsideBox(9, 3, 49));
            Assert.Equal(14UL, ZCurve.NextInsideBox(13, 3, 49));
            Assert.Equal(19UL, ZCurve.NextInsideBox(18, 3, 49));
            Assert.Equal(49UL, ZCurve.NextInsideBox(48, 3, 49));

            Assert.Equal(0UL, ZCurve.NextInsideBox(49, 3, 49));
            Assert.Equal(0UL, ZCurve.NextInsideBox(54, 54, 54));

            // What if z > qhi? Only keys 000 or 100 or 101 can occur,
            // drilling down (possibly cutting off lower parts of the
            // query box) until the box is below and z is above the
            // dividing line (key 100) and we return the result so far,
            // which is zero (result's initial value).

            Assert.Equal(0UL, ZCurve.NextInsideBox(50, 3, 49, 5));             // x within, y beyond
            Assert.Equal(0UL, ZCurve.NextInsideBox(51, 3, 49, 5));             // x within, y beyond
            Assert.Equal(0UL, ZCurve.NextInsideBox(52, 3, 49, 5));             // x beyond, y within
            Assert.Equal(0UL, ZCurve.NextInsideBox(53, 3, 49, 5));             // x beyond, y within
            Assert.Equal(0UL, ZCurve.NextInsideBox(54, 3, 49, 5));             // both x and y beyond

            // Enumerate cells within query box qlo..qhi:

            var result   = new List <ulong>();
            var expected = new ulong[] { 3, 6, 7, 9, 11, 12, 13, 14, 15, 18, 19, 24, 25, 26, 27, 33, 36, 37, 48, 49 };

            ulong qlo = ZCurve.Encode(1U, 1U);             // 3
            ulong qhi = ZCurve.Encode(5U, 4U);             // 49
            ulong cur = qlo;

            while (true)
            {
                result.Add(cur);
                cur += 1;
                if (cur > qhi)
                {
                    break;
                }
                const int starti = 5;
                if (!ZCurve.IsInsideBox(cur, qlo, qhi))
                {
                    cur = ZCurve.NextInsideBox(cur, qlo, qhi, starti);
                }
            }

            Assert.Equal(expected, result);
        }
예제 #2
0
        public void QueryBlocksTrial()
        {
            // Expect shortest ordered sequence of blocks covering query box

            // Query box:
            ulong qlo = ZCurve.Encode(1U, 1U);             // 3
            ulong qhi = ZCurve.Encode(5U, 4U);             // 49

            // Expected result: 3 6 7 9 11 (12..15) 18 19 (24..27) 33 36 37 48 49
            var starts   = new ulong[] { 3, 6, 7, 9, 11, 12, 18, 19, 24, 33, 36, 37, 48, 49 };
            var levels   = new[] { 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 };
            var expected = starts.Zip(levels, (s, l) => new ZCurve.Block(s, l)).ToList();
            var actual   = new List <ZCurve.Block>();

            ulong first = ZCurve.FirstInBlock(qlo, 0);
            ulong last  = ZCurve.FirstInBlock(qhi, 0);

            for (ulong cursor = first; ;)
            {
                int   level     = ZCurve.LargestLevel(cursor, last);
                ulong increment = ZCurve.CellsPerBlock(level);

                actual.Add(new ZCurve.Block(cursor, level));

                cursor += increment;

                if (cursor > last)
                {
                    break;
                }

                if (!ZCurve.IsInsideBox(cursor, first, last))
                {
                    cursor = ZCurve.NextInsideBox(cursor, first, last);
                }
            }

            Assert.Equal(expected, actual);
        }